AC automata, Bit,dfs sequence.
All of the STL in this article is because of its lazy implementation.
First x appears in Y, which means Y-node can go back down fail.
Build a fail number in reverse and then make the DFS sequence. Find out how many y the interval x corresponds to.
Then use the offline operation to save the x that each y needs to calculate in advance.
#include <cstdio>#include<algorithm>#include<cstring>#include<queue>#include<vector>using namespacestd;Const intMAXN =100000+Ten;CharS[MAXN];inta[maxn][ -];intG[maxn],v[maxn],next[maxn],eid;intpos[maxn],cnt;intfa[maxn],fail[maxn],l[maxn],r[maxn],query[maxn][3];intM,n,u,dfn,vid;vector<int>Q[maxn];queue<int>Q;structBIT {inta[maxn<<1],n; intLowbit (intx) {return(X &-x); } voidAddintXintd) {//printf ("C%d%d\n", x,d); for(; x<=n;x+=lowbit (x)) a[x]+=D; //printf ("C"); } intQueryintx) {intres=0; for(; x;x-=lowbit (x)) res+=A[x]; returnRes; } voidInitint_n) {N=_n; }}bit;voidAddedge (intAintb) {V[eid]=b; Next[eid]=g[a]; g[a]=eid++;}voidDfsintu) {L[u]=++DFN; for(intI=g[u];~i;i=Next[i]) DFS (v[i]); R[u]=DFN;}voidGet_trie () { for(intI=0;i< -; i++) a[0][i]=1; intp=1, c;vid=1; for(intI=0; i<n;i++) { //printf ("f[%d] =%d\n", i,p); if(s[i]=='P') pos[++cnt]=p; Else if(s[i]=='B') p=Fa[p]; Else{C=s[i]-'a'; if(!A[p][c]) a[p][c]=++vid,fa[vid]=p; P=A[p][c]; } //printf ("f[%d] =%d\n", i,p); }}voidDebugintp) {}voidGet_fail () {fail[1]=0; Q.push (1); while(!Q.empty ()) {u=Q.front (); Q.pop (); for(intk=0,p;k< -; k++) if(A[u][k]) { for(P=fail[u];p &&!a[p][k];p =fail[p]); FAIL[A[U][K]]=A[p][k]; Q.push (A[u][k]); } }}voidGet_tree () { for(intI=1; i<=vid;i++) Addedge (fail[i],i); DFS (1);}voidbuild () {memset (g,-1,sizeof(g)); scanf ("%s", s); n=strlen (s); Get_trie (); //Debug (1);Get_fail (); Get_tree (); scanf ("%d",&m); for(intI=1; i<=m;i++) {scanf ("%d%d", &query[i][0],&query[i][1]); query[i][0]=pos[query[i][0]]; query[i][1]=pos[query[i][1]]; q[query[i][1]].push_back (i); } }voidsolve () {Bit.init (n<<1); intp=1; for(intI=0; i<n;i++) { //printf ("s[i]=%c\n", S[i]); if(s[i]=='P') for(intj=0; J<q[p].size (); j + +) query[q[p][j]][2]=bit.query (r[query[q[p][j]][0]])-bit.query (l[query[q[p][j]][0]]-1); Else if(s[i]=='B') Bit.add (l[p],-1), p=Fa[p]; Elsep=a[p][s[i]-'a'],bit.add (L[p],1); //printf ("%d\n", I); } for(intI=1; i<=m;i++) printf ("%d\n", query[i][2]);}intMain () {build (); Solve (); return 0;}
2434: [Noi2011] Ali's typewriter