弱爆了...
发现我的代码实现能力太弱了...
今天打阿里的打字机,调了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.