题意:
给一个长度为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;
}