...其實暑假的時候寫過一次,不過那時候對這道題理解不是很深,所以重寫了一遍....
嘗試用新的模版去寫,然後發現新的模版裡面我把fail並到next,以省去多次的while取點,但是對於這道題,fail是必須用到的,因為要dp...所以不能並進去...於是只能乖乖滾回去寫原來的方法,每次都去往回while fail節點...然後就是pd陣列的傳遞,要和fail所連的點保持一直,因為是bfs下來的...
然後...**如下
1const maxn=6419
;2 maxs=25
;3 vv=10007;4
var5 next:array[0..maxn,0..maxs] of
longint;
6 pd:array[0..maxn] of
boolean;
7 f:array[0..maxn] of
longint;
8 q:array[0..maxn] of
longint;
9 dp:array[0..maxn,0..105] of
longint;
10s:string;
11head,tail,root,n,m,tot:longint;
1213
procedure push(x:longint); begin inc(tail); q[tail]:=x; end;14
15function
new:longint;
16var
i:longint;
17begin
18 pd[tot]:=false;
19for i:= 0
to maxs do next[tot,i]:=-1
;20 inc(tot); exit(tot-1
);21
end;
2223
procedure
insert(s:string);
24var
c,i,v:longint;
25begin
26 v:=root;
27for i:= 1
to length(s) do
28begin
29 c:=ord(s[i])-65;30
if next[v,c]=-1
then next[v,c]:=new;
31 v:=next[v,c];
32end
;33 pd[v]:=true;
34end;35
36procedure
build;
37var
v,tmp,i:longint;
38begin
39 f[root]:=root;
40 head:=1; tail:=0;41
for i:= 0
to maxs do
42if next[root,i]<>-1
then
43begin f[next[root,i]]:=root; push(next[root,i]); end;44
while head<=tail do
45begin
46 v:=q[head]; inc(head);
47for i:= 0
to maxs do
48if next[v,i]<>-1
then
49begin
50push(next[v,i]);
51 tmp:=f[v];
52while (tmp<>root) and (next[tmp,i]=-1) do tmp:=f[tmp];
53if next[tmp,i]<>-1
then tmp:=next[tmp,i];
54if tmp=-1
then f[next[v,i]]:=root else f[next[v,i]]:=tmp;
55if
not pd[next[v,i]] then pd[next[v,i]]:=pd[tmp];
56end;57
end;
58end;59
60procedure
solve;
61var
i,j,k,v,cnt,ans:longint;
62begin
63 dp[0,0]:=1;64
for i:= 1
to m do
65for j:= root to tot do
66if (not pd[j]) and (dp[j,i-1]>0) then
67for k:= 0
to maxs do
68begin
69 v:=j;
70while (next[v,k]=-1) and (v<>root) do v:=f[v];
71if next[v,k]<>-1
then v:=next[v,k];
72if
not pd[v] then dp[v,i]:=(dp[v,i]+dp[j,i-1]) mod
vv;73
end;
74 cnt:=0;75
for i:= 0
to tot do cnt:=(cnt+dp[i,m]) mod
vv;76 ans:=1;77
for i:= 1
to m do ans:=(ans*26) mod
vv;78 ans:=(((ans-cnt) mod vv+vv) mod
vv);
79writeln(ans);
80end;81
82procedure
init;
83var
i:longint;
84begin
85readln(n,m);
86 root:=new;
87for i:= 1
to n do
88begin
89readln(s);
90insert(s);
91end;92
build;
93end;94
95begin
96init;
97solve
98 end.
BZOJ1030 JSOI2007文字生成器
比起前面hnoi的gt考試,貌似這題是多模式串。然後我滾去學ac自動機了。發現還是很好寫的。ac自動機部分見筆記 搞出自動機之後,f i j 表示自動機上第i個節點匹配到第j個字元不可讀文字的數量,然後自己yy一下轉移 include include include define n 10005 d...
bzoj1030 JSOI2007 文字生成器
傳送門 思路 直接算好像比較困難,所以考慮先算不可讀的串的個數,再拿總串數去減。不可讀的串的數量就是在ac自動機上走m步而不經過結尾節點 包括結尾點和fail指向結尾點的節點 的路徑條數。這個怎麼求呢?設f i j 表示走i步,現在在j號節點的路徑條數。那麼f i j 可以轉移f i 1 son j...
bzoj1030 JSOI2007 文字生成器
time limit 1 sec memory limit 162 mb submit 2891 solved 1193 submit status discuss jsoi交給隊員zyx乙個任務,編制乙個稱之為 文字生成器 的電腦軟體 該軟體的使用者是一些低幼人群,他們現在使用的是gw文字生成器v...