结论:假如存在一个子串和为x,那么一定存在一个前缀,和为x或x+1
证明:可以认为原串是由和为x的串在开头和结尾添加若干数得到,再后边添加数不会对产生和为x或x+1的前缀产生影响,所以只考虑在前边添加数,认为后边多余的数可以删掉
若原来是一个和为x或x+1的串,那么如果在前边添加的数和最后一个数相等,去掉最后一个数之后依然是一个和为x或x+1的串
考虑新添加的数和最后的数不同的情况
若原来和为x,在前边添加1,那么这就变成了和为x+1的串;再前边添加2,把结尾的1去掉,则变成了和为x+1的串
若原来和为x+1,在前边添加1,把后边的2删掉,就变成了和为x的串;在前边添加2,把结尾的1去掉之后,若新的结尾是1,把1去掉之后变成和为x+1的串,若新的结尾是2,把2去掉之后变为和为x的串。一定存在新的结尾,即原来串的长度不可能为1,因为串的和为x+1而最后一个数是1,并且x>0
知道这些之后,我们记录一下每个前缀和的值和位置,然后若查询x,如果有和为x的前缀直接输出,否则考虑如何把和为x+1的前缀变成和为x的子串
设当前这个前缀区间为[l,r],因为不存在和为x的前缀,所以最后一个数a[r]一定是1
我们把区间左右端点不断同时右移1个单位,当出现a[l]=1时,我们可以另x++得到和为x的子串,当a[r+1]=1时,我们可以另l++,r++得到和为x的子串
所以记录每个点之后最长连续2的长度,然后就可以搞了
若没有和为x或x+1的前缀,或者把r移到了n都没有找到合适的区间,那么就是无解
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<queue>
#include<stack>
using namespace std;
#define MAXN 1000010
#define MAXM 1010
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
#define ll long long
int n,m;
char a[MAXN];
int s[MAXN],nxt[MAXN];
int v[MAXN<<1];
int main(){
int i,x;
scanf("%d%d%s",&n,&m,a+1);
for(i=1;i<=n;i++){
s[i]=s[i-1]+1+(a[i]=='T');
v[s[i]]=i;
}
x=n+1;
for(i=n;i;i--){
if(a[i]=='W'){
x=i;
}
nxt[i]=x-i;
}
while(m--){
scanf("%d",&x);
if(v[x]){
printf("%d %d\n",1,v[x]);
}else if(v[x+1]){
int l=1,r=v[x+1];
if(nxt[l]<nxt[r]){
r+=nxt[l];
l+=nxt[l]+1;
printf("%d %d\n",l,r);
}else if(r+nxt[r]<=n){
l+=nxt[r];
r+=nxt[r];
printf("%d %d\n",l,r);
}else{
printf("NIE\n");
}
}else{
printf("NIE\n");
}
}
return 0;
}
/*
*/