利用了bzoj3172提到的性质,x串在y串中的出现的次数即为在fail树上以x结尾节点为根的子树中有多少个节点在y串上
所以很明显我们要离线解决,我们先把询问按y分类存起来
然后我们顺着操作顺序来,出现一个字符就把fail树上对应节点标为1,删除之后就改为0;
当一个串输出之后,我们就统计跟他有关的询问(查询x串结尾节点子树和)
这种问题显然用dfs序+树状数组解决

  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.
View Code

 

posted on 2015-02-07 10:51  acphile  阅读(161)  评论(0编辑  收藏  举报