1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
const int N=2e5+10; namespace MAIN{ int n,q; char str[N]; int fa[N],Fa[N]; vector<int> G[N],E[N]; int rt[N],ls[N*30],rs[N*30],sum[N*30]; int dfn[N],low[N],idx,pos[N]; void dfs(res x){ pos[dfn[x]=++idx]=x; for(auto tox:G[x])dfs(tox); low[x]=idx; } int Dfn[N],Low[N]; void Dfs(res x){ Dfn[x]=++idx; for(auto tox:E[x])Dfs(tox); Low[x]=idx; } int tot; void insert(res &rt,res RT,res l,res r,const res &p){ rt=++tot,ls[rt]=ls[RT],rs[rt]=rs[RT],sum[rt]=sum[RT]+1; if(l==r){sum[rt]=sum[RT]+1;return;} res mid=(l+r)>>1; if(p<=mid)insert(ls[rt],ls[RT],l,mid,p); else insert(rs[rt],rs[RT],mid+1,r,p); } int query(res rt,res RT,res l,res r,const res &L,const res &R){ if(!RT)return 0; if(L<=l&&r<=R)return sum[RT]-sum[rt]; res mid=(l+r)>>1,ret=0; if(L<=mid)ret=query(ls[rt],ls[RT],l,mid,L,R); if(R>mid)ret+=query(rs[rt],rs[RT],mid+1,r,L,R); return ret; } inline void MAIN(){ n=read(),q=read(),scanf("%s",str+1); for(res i=2;i<=n;i++){ res now=fa[i-1]; while(str[now+1]!=str[i]&&now)now=fa[now]; fa[i]=now+(str[now+1]==str[i]); } Fa[n]=n+1; for(res i=n-1;i;i--){ res now=Fa[i+1]; while(str[now-1]!=str[i]&&now<=n)now=Fa[now]; Fa[i]=now-(str[now-1]==str[i]); } for(res i=0;i<=n+1;i++)vector<int>().swap(G[i]),vector<int>().swap(E[i]),rt[i]=0; for(res i=1;i<=n;i++)G[fa[i]].pb(i),E[Fa[i]].pb(i); idx=0,dfs(0),idx=0,Dfs(n+1); for(res i=1;i<=tot;i++)ls[i]=rs[i]=sum[i]=0; tot=0; for(res i=1;i<=n+1;i++)insert(rt[i],rt[i-1],1,n+1,Dfn[pos[i]+1]); while(q--){ res l=read(),r=n-read()+1; printf("%d\n",query(rt[dfn[l]-1],rt[low[l]],1,n+1,Dfn[r],Low[r])); } } }
|