BZOJ1030 (JSOI2007 文本生成器)
传送门:网站挂了。。百度去吧。。
BZOJ1030 (JSOI2007 文本生成器)
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
A
B
Sample Output
100
1 #include<set> 2 #include<map> 3 #include<queue> 4 #include<cstdio> 5 #include<cstdlib> 6 #include<cstring> 7 #include<iostream> 8 #include<algorithm> 9 using namespace std; 10 const int SONS=26; 11 const int MOD=10007; 12 const int MAXN=110*60; 13 #define For(i,n) for(int i=1;i<=n;i++) 14 #define For0(i,n) for(int i=0;i<n;i++) 15 #define Rep(i,l,r) for(int i=l;i<=r;i++) 16 #define Down(i,r,l) for(int i=r;i>=l;i--) 17 char st[MAXN/100]; 18 int n,m,dp[MAXN/100][MAXN],ans; 19 struct trie{ 20 int sz,ch[MAXN][SONS],q[MAXN],next[MAXN]; 21 short int fn[MAXN]; 22 trie(){sz=0;memset(ch[0],0,sizeof(ch[0]));} 23 void insert(char *s){ 24 int len=strlen(s),cur=0; 25 For0(i,len){ 26 int id=s[i]-'A'; 27 if(!ch[cur][id]) ch[cur][id]=++sz; 28 cur=ch[cur][id]; 29 } 30 fn[cur]=1; 31 } 32 void BuildAC(){ 33 int l=0,r=0; 34 For0(i,SONS) 35 if(ch[0][i]) q[++r]=ch[0][i]; 36 while(l<r){ 37 int cur=q[++l]; 38 For0(i,SONS) 39 if(!ch[cur][i]) ch[cur][i]=ch[next[cur]][i]; 40 else{ 41 q[++r]=ch[cur][i]; 42 next[ch[cur][i]]=ch[next[cur]][i]; 43 if(fn[next[ch[cur][i]]]) fn[ch[cur][i]]=1; 44 } 45 } 46 } 47 }ac; 48 49 void DP(){ 50 dp[0][0]=1; 51 For(i,m) 52 For0(j,ac.sz+1){ 53 if(ac.fn[j]) continue; 54 For0(k,SONS){ 55 int cur=ac.ch[j][k]; 56 if(ac.fn[cur]) continue; 57 dp[i][cur]=(dp[i][cur]+dp[i-1][j])%MOD; 58 } 59 } 60 For0(i,ac.sz+1) ans=(ans+dp[m][i])%MOD; 61 } 62 63 int main(){ 64 scanf("%d%d",&n,&m); 65 For(i,n){ 66 scanf("%s",&st); 67 ac.insert(st); 68 } 69 ac.BuildAC(); 70 DP(); 71 int tans=1;For(i,m) tans=(tans*26)%MOD; 72 printf("%d\n",(tans-ans+MOD)%MOD); 73 return 0; 74 }