【BZOJ1030】[JSOI2007]文本生成器

...其实暑假的时候写过一次,不过那时候对这道题理解不是很深,所以重写了一遍....

尝试用新的模版去写,然后发现新的模版里面我把fail并到next,以省去多次的while取点,但是对于这道题,fail是必须用到的,因为要DP...所以不能并进去...于是只能乖乖滚回去写原来的方法,每次都去往回while fail节点...然后就是pd数组的传递,要和fail所连的点保持一直,因为是BFS下来的...

然后...代码如下

 1 const maxn=6419;
 2  maxs=25;
 3  vv=10007;
 4 var
 5  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;
10  s:string;
11  head,tail,root,n,m,tot:longint;
12 
13 procedure push(x:longint); begin inc(tail); q[tail]:=x; end;
14 
15 function new:longint;
16 var i:longint;
17 begin
18  pd[tot]:=false;
19  for i:= 0 to maxs do next[tot,i]:=-1;
20  inc(tot); exit(tot-1);
21 end;
22 
23 procedure insert(s:string);
24 var c,i,v:longint;
25 begin
26  v:=root;
27  for i:= 1 to length(s) do
28   begin
29    c:=ord(s[i])-65;
30    if next[v,c]=-1 then next[v,c]:=new;
31    v:=next[v,c];
32   end;
33  pd[v]:=true;
34 end;
35 
36 procedure build;
37 var v,tmp,i:longint;
38 begin
39  f[root]:=root;
40  head:=1; tail:=0;
41  for i:= 0 to maxs do
42   if next[root,i]<>-1 then
43     begin f[next[root,i]]:=root; push(next[root,i]); end;
44  while head<=tail do
45   begin
46    v:=q[head]; inc(head);
47    for i:= 0 to maxs do
48     if next[v,i]<>-1 then
49      begin
50       push(next[v,i]);
51       tmp:=f[v];
52       while (tmp<>root) and (next[tmp,i]=-1) do tmp:=f[tmp];
53       if next[tmp,i]<>-1 then tmp:=next[tmp,i];
54       if tmp=-1 then f[next[v,i]]:=root else f[next[v,i]]:=tmp;
55       if not pd[next[v,i]] then pd[next[v,i]]:=pd[tmp];
56      end;
57   end;
58 end;
59 
60 procedure solve;
61 var i,j,k,v,cnt,ans:longint;
62 begin
63  dp[0,0]:=1;
64  for i:= 1 to m do
65   for j:= root to tot do
66    if (not pd[j]) and (dp[j,i-1]>0) then
67     for k:= 0 to maxs do
68      begin
69       v:=j;
70       while (next[v,k]=-1) and (v<>root) do v:=f[v];
71       if next[v,k]<>-1 then v:=next[v,k];
72       if 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);
79  writeln(ans);
80 end;
81 
82 procedure init;
83 var i:longint;
84 begin
85  readln(n,m);
86  root:=new;
87  for i:= 1 to n do
88   begin
89    readln(s);
90    insert(s);
91   end;
92  build;
93 end;
94 
95 Begin
96  init;
97  solve
98 End.

 

posted @ 2014-12-24 19:28  Ecsy  阅读(347)  评论(0编辑  收藏  举报