利用了bzoj3172提到的性质,x串在y串中的出现的次数即为在fail树上以x结尾节点为根的子树中有多少个节点在y串上
所以很明显我们要离线解决,我们先把询问按y分类存起来
然后我们顺着操作顺序来,出现一个字符就把fail树上对应节点标为1,删除之后就改为0;
当一个串输出之后,我们就统计跟他有关的询问(查询x串结尾节点子树和)
这种问题显然用dfs序+树状数组解决
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 const maxn=500000; 2 type node=record 3 y,next:longint; 4 end; 5 6 var i,j,n,m,len,tot,all,k,ll,rr,num,x,y,p:longint; 7 t:array[0..maxn,'a'..'z'] of longint; 8 q,pre,f,v,l,d,h,r,h2,ans,st,sum:array[0..maxn] of longint; 9 g,g2:array[0..maxn] of node; 10 c:char; 11 s:array[0..maxn] of char; 12 13 procedure add(x,y:longint); 14 begin 15 inc(num); 16 g[num].y:=y; 17 g[num].next:=h[x]; 18 h[x]:=num; 19 end; 20 21 procedure ac; 22 begin 23 fillchar(q,sizeof(q),0); 24 ll:=0; 25 rr:=0; 26 for c:='a' to 'z' do 27 if t[0,c]>0 then 28 begin 29 add(0,t[0,c]); 30 inc(rr); 31 q[rr]:=t[0,c]; 32 end; 33 while ll<>rr do 34 begin 35 inc(ll); 36 i:=q[ll]; 37 for c:='a' to 'z' do 38 if t[i,c]>0 then 39 begin 40 k:=t[i,c]; 41 inc(rr); 42 q[rr]:=k; 43 j:=f[i]; 44 while (j>0) and (t[j,c]=0) do j:=f[j]; 45 f[k]:=t[j,c]; 46 add(t[j,c],k); 47 end; 48 end; 49 end; 50 51 procedure dfs(x:longint); 52 var p:longint; 53 begin 54 inc(tot); 55 l[x]:=tot; 56 p:=h[x]; 57 while p<>0 do 58 begin 59 dfs(g[p].y); 60 p:=g[p].next; 61 end; 62 r[x]:=tot; 63 end; 64 65 procedure ins(x,y:longint); 66 begin 67 g2[i].y:=y; 68 g2[i].next:=h2[x]; 69 h2[x]:=i; 70 end; 71 72 procedure change(x,y:longint); 73 begin 74 while x<=tot do 75 begin 76 inc(sum[x],y); 77 inc(x,x and -x); 78 end; 79 end; 80 81 function get(x:longint):longint; 82 begin 83 get:=0; 84 while x>0 do 85 begin 86 inc(get,sum[x]); 87 dec(x,x and -x); 88 end; 89 end; 90 91 procedure main; 92 begin 93 readln(n); 94 for i:=1 to n do 95 begin 96 readln(x,y); 97 ins(y,x); 98 end; 99 j:=0;k:=0;m:=0; 100 for i:=1 to len do 101 begin 102 case s[i] of 103 'B':begin change(l[st[k]],-1);dec(k);j:=pre[j];end; 104 'P': 105 begin 106 inc(m);p:=h2[m]; 107 while p<>0 do 108 begin 109 ans[p]:=get(r[d[g2[p].y]])-get(l[d[g2[p].y]]-1); 110 p:=g2[p].next; 111 end; 112 end; 113 else begin 114 j:=t[j,s[i]]; 115 inc(k);st[k]:=j; 116 change(l[j],1); 117 end; 118 end; 119 end; 120 for i:=1 to n do writeln(ans[i]); 121 end; 122 123 begin 124 j:=0; 125 while not eoln do 126 begin 127 inc(len); 128 read(s[len]); 129 case s[len] of 130 'B':begin j:=pre[j];end; 131 'P':begin inc(tot);d[tot]:=j;v[j]:=1;end; 132 else begin 133 if t[j,s[len]]=0 then 134 begin 135 inc(all); 136 t[j,s[len]]:=all; 137 pre[all]:=j; 138 end; 139 j:=t[j,s[len]]; 140 end; 141 end; 142 end; 143 readln; 144 ac; 145 tot:=0; 146 dfs(0); 147 main; 148 end.