# bzoj3172

x串在y串中的出现的次数即为在fail树上以x结尾节点为根的子树中有多少个节点属于y串，这很好理解

 1 type node=record
2        po,next:longint;
3      end;
4
5 var e:array[0..1000010] of node;
6     trie:array[0..1000010,'a'..'z'] of longint;
7     q,f,p,w:array[0..1000010] of longint;
8     v:array[0..210] of longint;
9     t,i,j,k,n,l,len:longint;
10     s:ansistring;
11
13   begin
14     inc(len);
15     e[len].po:=y;
16     e[len].next:=p[x];
17     p[x]:=len;
18   end;
19
20 procedure bfs;
21   var x,y,h,r,j:longint;
22       c:char;
23   begin
24     h:=1;
25     r:=0;
26     for c:='a' to 'z' do
27       if trie[0,c]>0 then
28       begin
30         inc(r);
31         q[r]:=trie[0,c];
32       end;
33
34     while h<=r do
35     begin
36       x:=q[h];
37       for c:='a' to 'z' do
38         if trie[x,c]>0 then
39         begin
40           y:=trie[x,c];
41           inc(r);
42           q[r]:=y;
43           j:=f[x];
44           while (j>0) and (trie[j,c]=0) do j:=f[j];
45           f[y]:=trie[j,c];
47         end;
48       inc(h);
49     end;
50   end;
51
52 procedure dfs(x:longint);
53   var i,y:longint;
54   begin
55     i:=p[x];
56     while i<>0 do
57     begin
58       y:=e[i].po;
59       dfs(y);
60       w[x]:=w[y]+w[x];
61       i:=e[i].next;
62     end;
63   end;
64
65 begin
67   for i:=1 to n do
68   begin
70     j:=0;
71     l:=length(s);
72     for k:=1 to l do
73     begin
74       if trie[j,s[k]]=0 then
75       begin
76         inc(t);
77         trie[j,s[k]]:=t;
78       end;
79       j:=trie[j,s[k]];
80       inc(w[j]);
81     end;
82     v[i]:=j;
83   end;
84   bfs;
85   dfs(0);
86   for i:=1 to n do
87     writeln(w[v[i]]);
88 end.
ac自动机
  1 var h,rank,x,y,sum,sa:array[0..1010000] of longint;
2     f:array[0..1010000,0..30] of longint;
3     where,len,d:array[0..500] of longint;
4     now, k,ans,i,j,p,n,m,t,l,r:longint;
5     s,cc:ansistring;
6 function min(a,b:longint):longint;
7   begin
8     if a>b then exit(b) else exit(a);
9   end;
10
11 function lcp(a,b:longint):longint;
12   var k:longint;
13   begin
14     k:=trunc(ln(b-a+1)/ln(2));
15     exit(min(f[a,k],f[b-d[k]+1,k]));
16   end;
17
18 begin
20   for i:=1 to t do
21   begin
23     where[i]:=length(s)+1;
24     len[i]:=length(cc);
25     s:=s+cc;
26     if i<>t then s:=s+' ';
27   end;
28 {  for i:=1 to t do
29      writeln(where[i],' ',len[i]);}
30   n:=length(s);
31   for i:=1 to n do
32   begin
33     y[i]:=ord(s[i]);
34     inc(sum[y[i]]);
35   end;
36   m:=130;
37   for i:=2 to 130 do
38     inc(sum[i],sum[i-1]);
39   for i:=1 to n do
40   begin
41     sa[sum[y[i]]]:=i;
42     dec(sum[y[i]]);
43   end;
44   p:=1;
45   rank[sa[1]]:=1;
46   for i:=2 to n do
47   begin
48     if y[sa[i]]<>y[sa[i-1]] then inc(p);
49     rank[sa[i]]:=p;
50   end;
51   m:=p;
52   j:=1;
53   while m<n do
54   begin
55     y:=rank;
56     fillchar(sum,sizeof(sum),0);
57     p:=0;
58     for i:=n-j+1 to n do
59     begin
60       inc(p);
61       x[p]:=i;
62     end;
63     for i:=1 to n do
64       if sa[i]>j then
65       begin
66         inc(p);
67         x[p]:=sa[i]-j;
68       end;
69     for i:=1 to n do
70     begin
71       rank[i]:=y[x[i]];
72       inc(sum[rank[i]]);
73     end;
74     for i:=2 to m do
75       inc(sum[i],sum[i-1]);
76     for i:=n downto 1 do
77     begin
78       sa[sum[rank[i]]]:=x[i];
79       dec(sum[rank[i]]);
80     end;
81     p:=1;
82     rank[sa[1]]:=1;
83     for i:=2 to n do
84     begin
85       if (y[sa[i]]<>y[sa[i-1]]) or (y[sa[i]+j]<>y[sa[i-1]+j]) then inc(p);
86       rank[sa[i]]:=p;
87     end;
88     j:=j shl 1;
89     m:=p;
90   end;
91   h[1]:=0;
92   p:=0;
93   for i:=1 to n do
94   begin
95     if rank[i]=1 then continue;
96     j:=sa[rank[i]-1];
97     while s[i+p]=s[j+p] do inc(p);
98     h[rank[i]]:=p;
99     if p>0 then dec(p);
100   end;
101   k:=trunc(ln(n)/ln(2));
102   d[0]:=1;
103   for i:=1 to k do
104     d[i]:=d[i-1]*2;
105   for i:=1 to n do
106     f[i,0]:=h[i];
107   for j:=1 to k do
108     for i:=1 to n do
109       if i+d[j]-1<=n then
110       begin
111         f[i,j]:=min(f[i,j-1],f[i+d[j-1],j-1]);
112       end
113       else break;
114   for i:=1 to t do
115   begin
116     ans:=1;
117     k:=-1;
118     l:=1;
119     now:=rank[where[i]];
120     r:=now-1;
121     while l<=r do
122     begin
123       m:=(l+r) shr 1;
124       if lcp(m+1,now)>=len[i] then
125       begin
126         k:=m;
127         r:=m-1
128       end
129       else l:=m+1;
130     end;
131     if k<>-1 then ans:=ans+now-k;
132     l:=now+1;
133     k:=-1;
134     r:=n;
135     while l<=r do
136     begin
137       m:=(l+r) shr 1;
138       if lcp(now+1,m)>=len[i] then
139       begin
140         k:=m;
141         l:=m+1;
142       end
143       else r:=m-1;
144     end;
145     if k<>-1 then ans:=ans+k-now;
146     writeln(ans);
147   end;
148 end.

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