AmazingCounters.com

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

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 }

 

posted @ 2014-09-21 23:32  ZJDx1998  阅读(192)  评论(0编辑  收藏  举报