若能得到一個和為t的區間,那麼至少去掉兩端點中任意一個後必定能得到和為t-2的區間。
所以只需要分別找到和最大的和為奇數和偶數的區間,然後$O(n)$完成構造即可。
#include<cstdio> #define N 1000010 int n,m,i,s[N],b,c,d,t,l,r,f[N<<1][2];char a[N]; inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';} int main(){ read(n),read(m),scanf("%s",a+1); for(i=1;i<=n;i++)a[i]=a[i]=='W'?1:2,s[i]=s[i-1]+a[i]; for(b=1;b<=n;b++)if(s[b]&1)break; for(c=n;c;c--)if(s[c]&1)break; for(d=n;d;d--)if(!(s[d]&1))break; if(s[d]>t)t=s[d],l=1,r=d; if(s[c]-s[b]>t)t=s[c]-s[b],l=b+1,r=c; for(;l<=r&&t>0;t-=2){ f[t][0]=l,f[t][1]=r; if(a[l]==2)l++;else if(a[r]==2)r--;else l++,r--; } t=0; if(s[c]>t)t=s[c],l=1,r=c; if(s[d]-s[b]>t)t=s[d]-s[b],l=b+1,r=d; for(;l<=r&&t>0;t-=2){ f[t][0]=l,f[t][1]=r; if(a[l]==2)l++;else if(a[r]==2)r--;else l++,r--; } while(m--){ read(t); if(f[t][0])printf("%d %d\n",f[t][0],f[t][1]);else puts("NIE"); } return 0; }