弱爆了...

发现我的代码实现能力太弱了...

今天打阿里的打字机,调了2个小时...

总结一下

1.用两个链表,一个实现离线处理,一个实现fail树,采用link,next,value(保存关键信息):array[0..Maxn] of longint 的形式可以只写一个insert过程

2.代码中的sum多次重复使用,所以养成重复变量使用完后初始化的习惯(就在这儿坑了无数次...)

3.AC-automation用数组写比链表方便许多

4.树状数组可以用来动态统计子树的某一类子节点个数

贴一下苦逼的代码:

View Code
  1 Program print;
  2 
  3 Const Maxn=100000;
  4 
  5 var
  6     s:ansistring;
  7     m,sum:longint;
  8     link,next,value:array[0..1,0..Maxn] of longint;
  9 
 10     root:longint;
 11     node:array[0..Maxn,'a'..'z'] of longint;
 12     fail,pre,ask:array[0..Maxn] of longint;
 13     ans:array[0..Maxn] of longint;
 14 
 15     time:longint;
 16     enter,leave:array[0..Maxn] of longint;
 17     c:array[0..2*Maxn] of longint;
 18 
 19     procedure insert(u,v,w:longint);
 20     begin
 21         inc(sum);
 22         next[w,sum]:=link[w,u]; link[w,u]:=sum; value[w,sum]:=v;
 23     end;
 24 
 25     Procedure Init;
 26     var i,x,y:longint;
 27     begin
 28         readln(s);
 29         readln(m);
 30         for i:=1 to m do
 31             begin
 32                 readln(x,y);
 33                 insert(y,x,0);
 34             end;
 35         sum:=0;
 36     end;
 37 
 38     Procedure Build_AC_automation;
 39     var t,p,i:longint;
 40         head,tail:longint;
 41         q:array[0..Maxn] of longint;
 42         now,v:longint;
 43         ch:char;
 44 
 45     begin
 46         sum:=1; root:=1; t:=root;
 47         for i:=1 to length(s) do
 48             case s[i] of
 49                 'P':begin
 50                         inc(ask[0]);
 51                         ask[ask[0]]:=t;
 52                     end;
 53                 'B':t:=pre[t];
 54                 else
 55                     if node[t,s[i]]=0 then
 56                         begin
 57                             inc(sum); node[t,s[i]]:=sum;
 58                             pre[node[t,s[i]]]:=t; t:=sum;
 59                         end else t:=node[t,s[i]];
 60             end;
 61         head:=1; tail:=1; q[1]:=root; fail[root]:=root; sum:=0;
 62         while head<=tail do
 63             begin
 64                 now:=q[head]; inc(head);
 65                 for ch:='a' to 'z' do
 66                     begin
 67                         if node[now,ch]=0 then continue;
 68                         v:=fail[now];
 69                         while (v<>root) and (node[v,ch]=0) do v:=fail[v];
 70                         if (now<>root) and (node[v,ch]>0) then v:=node[v,ch];
 71                         fail[node[now,ch]]:=v;
 72                         insert(v,node[now,ch],1);
 73                         inc(tail); q[tail]:=node[now,ch];
 74                     end;
 75             end;
 76     end;
 77 
 78     Procedure DFS(t:longint);
 79     var p:longint;
 80     begin
 81         inc(time); enter[t]:=time;
 82         p:=link[1,t];
 83         while p>0 do
 84             begin
 85                 //writeln(t,'-->',value[1,p]);
 86                 DFS(value[1,p]);
 87                 p:=next[1,p];
 88             end;
 89         leave[t]:=time;
 90     end;
 91 
 92     Function lowbit(t:longint):longint;
 93     begin
 94         exit(t and  (t xor (t-1)));
 95     end;
 96 
 97     Procedure Update(t,v:longint);
 98     begin
 99         while t<=time do
100             begin
101                 inc(c[t],v);
102                 t:=t+lowbit(t);
103             end;
104     end;
105 
106     Function Getsum(t:longint):longint;
107     var sum:longint;
108     begin
109         sum:=0;
110         while t>0 do
111             begin
112                 sum:=sum+c[t];
113                 t:=t-lowbit(t);
114             end;
115         exit(sum);
116     end;
117 
118     Procedure Work;
119     var t,p,i:longint;
120     begin
121         sum:=0; t:=root;
122         for i:=1 to length(s) do
123             case s[i] of
124                 'P':begin
125                         inc(sum);
126                         p:=link[0,sum];
127                         while p>0 do
128                             begin
129                                 ans[p]:=getsum(leave[ask[value[0,p]]])-getsum(enter[ask[value[0,p]]]-1);
130                                 p:=next[0,p];
131                             end;
132                     end;
133                 'B':begin
134                         Update(enter[t],-1);
135                         t:=pre[t];
136                     end
137                 else
138                     begin
139                         t:=node[t,s[i]];
140                         Update(enter[t],1);
141                     end;
142             end;
143         for i:=1 to m do writeln(ans[i]);
144     end;
145 
146 begin
147     Init;
148     Build_AC_automation;
149     time:=0; DFS(root);
150     Work;
151 end.

 

posted on 2012-07-04 10:46  爱宝宝  阅读(132)  评论(0编辑  收藏  举报

导航