BZOJ1030 JSOI2007 文字生成器

2022-03-30 20:42:55 字數 3158 閱讀 6593

...其實暑假的時候寫過一次,不過那時候對這道題理解不是很深,所以重寫了一遍....

嘗試用新的模版去寫,然後發現新的模版裡面我把fail並到next,以省去多次的while取點,但是對於這道題,fail是必須用到的,因為要dp...所以不能並進去...於是只能乖乖滾回去寫原來的方法,每次都去往回while fail節點...然後就是pd陣列的傳遞,要和fail所連的點保持一直,因為是bfs下來的...

然後...**如下

1

const 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...