题意:
给一个长度为N的字符串,表示有N个字符可用。
再给p个不能含有的病毒串。
为你长度为M的串不含有任意一个病毒串的方案数。
思路:
由于不需要取模,50^50需要用到高精度。
因为题目的字符串大于32所以可以直接scanf输入。
输入完map一下就好了。
就是裸的自动机dp了。
代码:
#include"stdio.h" #include"algorithm" #include"string.h" #include"iostream" #include"queue" #include"map" #include"string" #define mod 998244353 #define ll long long using namespace std; map<char,int>mp; struct trie { int mark,id; trie *next[55],*fail; trie() { memset(next,0,sizeof(next)); fail=NULL; mark=0; } }; trie *node[1000],*root; int triecont,n; void init(char *v) { trie *p=root; for(int i=0;v[i]!='\0';i++) { int tep=mp[v[i]]; if(p->next[tep]==NULL) { p->next[tep]=new trie(); p->next[tep]->id=triecont; node[triecont++]=p->next[tep]; } p=p->next[tep]; } p->mark=1; } void getac() { queue<trie*>q; q.push(root); while(!q.empty()) { trie *p=q.front(); q.pop(); for(int i=0;i<n;i++) { if(p->next[i]==NULL) { if(p==root) p->next[i]=root; else p->next[i]=p->fail->next[i]; } else { if(p==root) p->next[i]->fail=root; else p->next[i]->fail=p->fail->next[i]; q.push(p->next[i]); if( p!=root && p->fail->next[i]->mark==1) p->next[i]->mark=1; } } } } int dp[55][123][123]; int main() { int m,p; while(scanf("%d%d%d",&n,&m,&p)!=-1) { triecont=0; root=new trie(); root->id=triecont; node[triecont++]=root; mp.clear(); char x[123]; getchar(); gets(x); for(int i=0;i<n;i++) mp[x[i]]=i; for(int i=0;i<p;i++) { gets(x); init(x); } getac(); memset(dp,0,sizeof(dp)); dp[0][0][100]=1; for(int i=1;i<=m;i++) { for(int j=0;j<triecont;j++) { for(int k=0;k<n;k++) { trie *p=node[j]->next[k]; if(p->mark==1) continue; for(int l=100;l>=1;l--) dp[i][p->id][l]+=dp[i-1][j][l]; for(int l=100;l>=1;l--) { if(dp[i][p->id][l]>9) { dp[i][p->id][l-1]+=dp[i][p->id][l]/10; dp[i][p->id][l]%=10; } } } } } int ans[123]; memset(ans,0,sizeof(ans)); for(int i=0;i<triecont;i++) { for(int j=100;j>=1;j--) ans[j]+=dp[m][i][j]; for(int j=100;j>=1;j--) { if(ans[j]>9) { ans[j-1]+=ans[j]/10; ans[j]%=10; } } } int j; for(j=0;j<=100;j++) if(ans[j]) break; if(j==101) puts("0"); else { for(j=j;j<=100;j++) printf("%d",ans[j]); puts(""); } } return 0; }
时间: 2024-11-06 07:53:30