#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
vector<int> getnxt(string s) {
int n = (int)s.length();
vector<int> pi(n);
for (int i = 1; i < n; i++) {
int j = pi[i - 1];
while (j > 0 && s[i] != s[j]) j = pi[j - 1];
if (s[i] == s[j]) j++;
pi[i] = j;
}
return pi;
}
int in[N],out[N],dfn;
struct node{
int to,nxt;
}d[N];int head[N],tot=0;
string s;int ans[N];
struct Node{
int r,id;
};vector<Node> v[N];
int T,n,q;vector<int> nxt;
void add(int a,int b){d[++tot]={b,head[a]};head[a]=tot;}
void dfs(int x){
in[x]=++dfn;
for(int i=head[x];i;i=d[i].nxt){
int v=d[i].to;
dfs(v);
}
out[x]=dfn;
}
struct BIT{
int q[N];
BIT(){memset(q,0,sizeof(q));}
void add(int loc,int x){for(int i=loc;i<N;i+=i&-i)q[i]+=x;}
int get_sum(int x){int ret=0;for(int i=x;i;i-=i&-i)ret+=q[i];return ret;}
}bit1;
void init(){
// bit1.init(N-1);
memset(head,0,sizeof head);
memset(ans,0,sizeof ans);
for(int i=1;i<=n;i++) v[i].clear();
dfn=tot=0;
}
void dfs2(int x){
for(int i=0;i<v[x].size();i++){
Node tp=v[x][i];
ans[tp.id]-=bit1.get_sum(out[tp.r])-bit1.get_sum(in[tp.r]-1);
}
bit1.add(in[n-x],1);
for(int i=head[x];i;i=d[i].nxt){
int v=d[i].to;
dfs2(v);
}
for(int i=0;i<v[x].size();i++){
Node tp=v[x][i];
ans[tp.id]+=bit1.get_sum(out[tp.r])-bit1.get_sum(in[tp.r]-1);
}
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&q);cin>>s;
init();
reverse(s.begin(),s.end());
nxt=getnxt(s);
for(int i=0;i<n;i++){add(nxt[i],i+1);}
dfs(0);
reverse(s.begin(),s.end());
memset(head,0,sizeof head);
nxt=getnxt(s);
for(int i=0;i<n;i++){add(nxt[i],i+1);}
for(int i=1;i<=q;i++){
int l,r;scanf("%d%d",&l,&r);
v[l].push_back({r,i});
}
dfs2(0);
for(int i=1;i<=q;i++){
printf("%d\n",ans[i]);
}
}
}
Pty loves string(KMP+fail+树状数组
最新推荐文章于 2022-03-14 18:13:28 发布