AC自动机+树状数组。
先把fail边反向建出fail树来。。
第x个字符串在第y个字符串中出现了多少次。对于y的每个前缀,如果它结尾可以通过fail跳到x的结尾的话,那么就出现了x。。
也就是查询x的fail子树中,有多少个y的节点。
在trie上暴力跑,在树状数组上加入根到当前节点路径上的点(将对应dfn值所在的地方+1),
跑到y的结束节点时,对于每个对应的查询x,求出x的子树中有多少个点就行了。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #define ll long long 6 using namespace std; 7 const int maxn=100233; 8 struct zs{int too,pre;}e[maxn],e1[maxn];int tot,last[maxn],tot1,last1[maxn]; 9 int too[maxn],pre[maxn],id[maxn],la[maxn],tt; 10 int L[maxn],R[maxn],ed[maxn],tim; 11 int t[maxn]; 12 int fail[maxn],ch[maxn][26],dl[maxn],fa[maxn]; 13 int i,j,k,n,m,cnt,node; 14 int ans[maxn]; 15 char s[maxn]; 16 17 int ra;char rx; 18 inline int read(){ 19 rx=getchar(),ra=0; 20 while(rx<'0'||rx>'9')rx=getchar(); 21 while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra; 22 } 23 inline void insert(int a,int b){e[++tot].too=b,e[tot].pre=last[a],last[a]=tot;} 24 inline void getfail(){ 25 int l=0,r=1,i,now,p;dl[1]=0; 26 while(l<r){ 27 now=dl[++l]; 28 for(i=0;i<26;i++)if(ch[now][i]){ 29 dl[++r]=ch[now][i]; 30 for(p=fail[now];p&&!ch[p][i];p=fail[p]); 31 fail[ch[now][i]]=!now?0:ch[p][i],insert(fail[ch[now][i]],ch[now][i]); 32 } 33 } 34 } 35 void dfs(int x){ 36 L[x]=++tim; 37 for(int i=last[x];i;i=e[i].pre)dfs(e[i].too); 38 R[x]=tim; 39 } 40 inline void ins(int a,int b){too[++tt]=b,id[tt]=i,pre[tt]=la[a],la[a]=tt;} 41 inline void insgg(int a,int b){e1[++tot1].too=b,e1[tot1].pre=last1[a],last1[a]=tot1;} 42 43 inline void add(int x){while(x<=node)t[x]++,x+=x&-x;} 44 inline void del(int x){while(x<=node)t[x]--,x+=x&-x;} 45 inline int query(int l,int r){ 46 int sm=0;l--; 47 while(r)sm+=t[r],r-=r&-r; 48 while(l)sm-=t[l],l-=l&-l;return sm; 49 } 50 void dfs2(int x){ 51 int i,x1,y,j;//printf("in: %d ",x); 52 if(x)add(L[x]); 53 for(i=last1[x];i;i=e1[i].pre) 54 for(y=e1[i].too,j=la[y];j;j=pre[j]) 55 x1=too[j],ans[id[j]]=query(L[ed[x1]],R[ed[x1]]); 56 for(i=0;i<26;i++)if(ch[x][i])/*printf("%d-->%d ",x,ch[x][i]),*/dfs2(ch[x][i]); 57 // printf("out: %d ",x); 58 if(x)del(L[x]); 59 } 60 int main(){ 61 scanf("%s",s+1),n=strlen(s+1); 62 int now=0; 63 for(i=1;i<=n;i++){ 64 if(s[i]=='P')cnt++,ed[cnt]=now,insgg(now,cnt);else 65 if(s[i]=='B')now=fa[now];else 66 if(!ch[now][s[i]-'a'])ch[now][s[i]-'a']=++node,fa[node]=now,now=node; 67 else now=ch[now][s[i]-'a']; 68 }node++; 69 getfail(); 70 dfs(0); 71 m=read(); 72 for(i=1;i<=m;i++)ins(read(),read()); 73 dfs2(0); 74 for(i=1;i<=m;i++)printf("%d ",ans[i]); 75 }