1030: [JSOI2007]文本生成器 - BZOJ

Description

JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版。该软件可以随机生成一些文章―――总是生成一篇长度固定且完全随机的文章—— 也就是说,生成的文章中每个字节都是完全随机的。如果一篇文章中至少包含使用者们了解的一个单词,那么我们说这篇文章是可读的(我们称文章a包含单词b,当且仅当单词b是文章a的子串)。但是,即使按照这样的标准,使用者现在使用的GW文本生成器v6版所生成的文章也是几乎完全不可读的。 ZYX需要指出GW文本生成器 v6生成的所有文本中可读文本的数量,以便能够成功获得v7更新版。你能帮助他吗?
Input

输入文件的第一行包含两个正整数,分别是使用者了解的单词总数N (<= 60),GW文本生成器 v6生成的文本固定长度M;以下N行,每一行包含一个使用者了解的单词。 这里所有单词及文本的长度不会超过100,并且只可能包含英文大写字母A..Z  。
Output

一个整数,表示可能的文章总数。只需要知道结果模10007的值。
Sample Input
2 2
A
B

Sample Output
100

 

在AC自动机上的dp

f[i,j,k]表示长度为i,在节点j,状态为k的方案数(k=0时为不匹配,k=1时为匹配)

 

  1 const
  2     maxn=6010;
  3     maxm=105;
  4     h=10007;
  5 type
  6     node=record
  7       fail:integer;
  8       flag:boolean;
  9       go:array['A'..'Z']of integer;
 10     end;
 11 var
 12     tree:array[0..maxn]of node;
 13     f:array[0..maxn,0..maxn,0..1]of integer;
 14     n,m,tot:longint;
 15     s:string;
 16 
 17 procedure insert;
 18 var
 19     i,j:longint;
 20 begin
 21     readln(s);
 22     j:=0;
 23     for i:=1 to length(s) do
 24       begin
 25         if tree[j].go[s[i]]=0 then
 26         begin
 27           inc(tot);
 28           tree[j].go[s[i]]:=tot;
 29         end;
 30         j:=tree[j].go[s[i]];
 31       end;
 32     tree[j].flag:=true;
 33 end;
 34 
 35 var
 36     q:array[0..maxn]of longint;
 37     head,tail:longint;
 38 
 39 procedure build;
 40 var
 41     i:char;
 42     k:longint;
 43 begin
 44     head:=1;
 45     tail:=1;
 46     q[1]:=0;
 47     while head<=tail do
 48       begin
 49         for i:='A' to 'Z' do
 50           if tree[q[head]].go[i]<>0 then
 51           begin
 52             inc(tail);
 53             q[tail]:=tree[q[head]].go[i];
 54             k:=tree[q[head]].fail;
 55             if k<>q[head] then
 56             begin
 57               while (k<>0) and (tree[k].go[i]=0) do
 58                 k:=tree[k].fail;
 59               tree[q[tail]].fail:=tree[k].go[i];
 60             end;
 61           end;
 62         for i:='A' to 'Z' do
 63           if tree[q[head]].go[i]=0 then tree[q[head]].go[i]:=tree[tree[q[head]].fail].go[i];
 64         if tree[tree[q[head]].fail].flag then tree[q[head]].flag:=true;
 65         inc(head);
 66       end;
 67 end;
 68 
 69 procedure init;
 70 var
 71     i:longint;
 72 begin
 73     readln(n,m);
 74     for i:=1 to n do
 75       insert;
 76     build;
 77 end;
 78 
 79 procedure work;
 80 var
 81     i,j,ans:longint;
 82     s:char;
 83 begin
 84     for s:='A' to 'Z' do
 85       if tree[tree[0].go[s]].flag then inc(f[1,tree[0].go[s],1])
 86       else inc(f[1,tree[0].go[s],0]);
 87     for i:=1 to m-1 do
 88       for j:=0 to tot do
 89         for s:='A' to 'Z' do
 90           if tree[tree[j].go[s]].flag then f[i+1,tree[j].go[s],1]:=(f[i+1,tree[j].go[s],1]+f[i,j,0]+f[i,j,1])mod h
 91           else
 92             begin
 93               f[i+1,tree[j].go[s],1]:=(f[i+1,tree[j].go[s],1]+f[i,j,1])mod h;
 94               f[i+1,tree[j].go[s],0]:=(f[i+1,tree[j].go[s],0]+f[i,j,0])mod h;
 95             end;
 96     ans:=0;
 97     for i:=0 to tot do
 98       ans:=(ans+f[m,i,1])mod h;
 99     writeln(ans);
100 end;
101 
102 begin
103     init;
104     work;
105 end.
View Code

 

posted @ 2014-03-31 17:09  Randolph87  阅读(329)  评论(0编辑  收藏  举报