1030: [JSOI2007]文本生成器
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3953 Solved: 1614[][][]Description
JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,
他们现在使用的是GW文本生成器v6版。该软件可以随机生成一些文章―――总是生成一篇长度固定且完全随机的文章—— 也就是说,生成的文章中每个字节都是完全随机的。如果一篇文章中至少包含使用者们了解的一个单词,那么我们说这篇文章是可读的(我们称文章a包含单词b,当且仅当单词b是文章a的子串)。但是,即使按照这样的标准,使用者现在使用的GW文本生成器v6版所生成的文章也是几乎完全不可读的?。ZYX需要指出GW文本生成器 v6生成的所有文本中可读文本的数量,以便能够成功获得v7更新版。你能帮助他吗?Input
输入文件的第一行包含两个正整数,分别是使用者了解的单词总数N (<= 60),GW文本生成器 v6生成的文本固
定长度M;以下N行,每一行包含一个使用者了解的单词。这里所有单词及文本的长度不会超过100,并且只可能包含英文大写字母A..ZOutput
一个整数,表示可能的文章总数。只需要知道结果模10007的值。
Sample Input
2 2 A B
Sample Output
100
题意:求长度为m且含有至少一个模板串的字符串个数
好神啊
含有至少一个不好求,那就求不含模板串的然后总数减
计数问题组合数学做不了就考虑DP
f[i][j]表示长度为i匹配到自动机上节点j的不含模板串的方案数
转移 f[i][j]-->f[i+1][t[j].ch[k]]
如何判断一个串不含模板串?首先f[i][j]已经保证1..i-1是不含模板串的啦,只要保证第i个字符加入后也不含就行了
ins时模板串终点打标记,本身且Fail祖先没有标记就说明AC自动机上j结尾的没有模板串
但是有的字符模板串里没有啊?给root把孩子补全就行了【实际上不补全也是可以的,反正默认走到了根,最后f[m][根]也统计】
思路和KMP一样,都是一边生成字符串一边在KMP/AC自动机上匹配,
#include#include #include #include using namespace std;const int N=105,M=6005,MOD=10007;int n,m;char s[N];struct node{ int ch[26],fail,val;}t[M];int sz;void ins(char s[]){ int u=0,n=strlen(s+1); for(int i=1;i<=n;i++){ int c=s[i]-'A'; if(!t[u].ch[c]) t[u].ch[c]=++sz; u=t[u].ch[c]; } t[u].val=1;}int q[M],head,tail;void getAC(){ head=tail=1; for(int i=0;i<26;i++){ if(!t[0].ch[i]) t[0].ch[i]=++sz; q[tail++]=t[0].ch[i]; } while(head!=tail){ int u=q[head++]; t[u].val|=t[t[u].fail].val; for(int i=0;i<26;i++){ int &v=t[u].ch[i]; if(!v) {v=t[t[u].fail].ch[i];continue;} t[v].fail=t[t[u].fail].ch[i]; q[tail++]=v; } }}int f[N][M],ans;void dp(){ f[0][0]=1; for(int i=1;i<=m;i++){ for(int j=0;j<=sz;j++) if(!t[j].val&&f[i-1][j]!=0) for(int k=0;k<26;k++) if(!t[t[j].ch[k]].val) f[i][t[j].ch[k]]=(f[i][t[j].ch[k]]+f[i-1][j])%MOD; } for(int j=0;j<=sz;j++) ans=(ans+f[m][j])%MOD;}int main(){ //freopen("in.txt","r",stdin); scanf("%d%d",&n,&m);//printf("hi %d %d nm\n",n,m); for(int i=1;i<=n;i++) scanf("%s",s+1),ins(s); getAC(); dp(); int tmp=1; for(int i=1;i<=m;i++) tmp=(tmp*26)%MOD; printf("%d",(tmp-ans+MOD)%MOD);}