Time Limit: 5000MS | Memory Limit: 10000K | |
Description
But after recent election of Mr. Grass Jr. as Freeland president some words offending him were declared unprintable and all sentences containing at least one of them were forbidden. The sentence S contains a word W if W is a substring of S i.e. exists such k >= 1 that S[k] = W[1], S[k+1] = W[2], ...,S[k+len(W)-1] = W[len(W)], where k+len(W)-1 <= M and len(W) denotes length of W. Everyone who uses a forbidden sentence is to be put to jail for 10 years.
Find out how many different sentences can be used now by freelanders without risk to be put to jail for using it.
Input
The second line contains exactly N different characters -- the letters of the Freish alphabet (all with ASCII code greater than 32).
The following P lines contain forbidden words, each not longer than min(M, 10) characters, all containing only letters of Freish alphabet.
Output
Sample Input
2 3 1
ab
bb
Sample Output
5
Source
#include<queue> #include<cstdio> #include<cstring> using namespace std; const int mod=1000000000; int n,m,p,id,len,root,tot=1; char s[101],ss[501]; bool mark[1001],v[1001][501]; int f[1001],trie[1001][501],mp[1001]; queue<int>q; struct bigint { int num[20]; bigint() { memset(num,0,sizeof(num)); num[0]=1; num[1]=0; } bigint(int i) { memset(num,0,sizeof(num)); num[0]=1; num[1]=i; } //void operator += (bigint b) //{ /*for(int i=num[0];i;i--) printf("%d",num[i]); putchar('+'); for(int i=b.num[0];i;i--) printf("%d",b.num[i]); putchar('=');*/ // num[0]=max(b.num[0],num[0]); // for(int i=1;i<=num[0];i++) // { // num[i]+=b.num[i]; // num[i+1]+=num[i]/10; // num[i]%=10; // } // if(num[num[0]+1]) num[0]++; /*for(int i=num[0];i;i--) printf("%d",num[i]); puts("");*/ // } void operator += (bigint b) { /*for(int i=num[0];i;i--) printf("%d",num[i]); putchar('+'); for(int i=b.num[0];i;i--) printf("%d",b.num[i]); putchar('=');*/ num[0]=max(num[0],b.num[0]); for(int i=1;i<=num[0];i++) num[i]+=b.num[i]; for(int i=1;i<=num[0];i++) { num[i+1]+=num[i]/mod; num[i]%=mod; } if(num[num[0]+1]) num[0]++; /*for(int i=num[0];i;i--) printf("%d",num[i]); puts("");*/ } void operator = (bigint b) { int lb=b.num[0]; for(int i=0;i<=lb;i++) num[i]=b.num[i]; } void output() { printf("%d",num[num[0]]); for(int i=num[0]-1;i;i--) printf("%09d",num[i]); } }; bigint dp[101][51]; bigint dfs(int now,int l) { if(!l) return bigint(1); if(v[now][l]) return dp[now][l]; v[now][l]=1; bigint x; for(int i=0;i<n;i++) if(!mark[trie[now][i]]) x+=dfs(trie[now][i],l-1); /* printf("%d %d: ",now,l); dp[now][l].output(); puts("");*/ dp[now][l]=x; return x; } struct ACautomata { int get(char c) { return mp[c]; } void insert() { len=strlen(s); root=1; for(int i=0;i<len;i++) { id=get(s[i]); if(!trie[root][id]) { trie[root][id]=++tot; memset(trie[tot],0,sizeof(trie[tot])); mark[tot]=0; } root=trie[root][id]; } mark[root]=true; } void getfail() { memset(f,0,sizeof(f)); for(int i=0;i<n;i++) trie[0][i]=1; q.push(1); int now,j; while(!q.empty()) { now=q.front(); q.pop(); for(int i=0;i<n;i++) { if(!trie[now][i]) { trie[now][i]=trie[f[now]][i]; //if(mark[trie[f[now]][i]]) mark[trie[now][i]]=true; continue; } q.push(trie[now][i]); j=f[now]; f[trie[now][i]]=trie[j][i]; if(mark[trie[j][i]]) mark[trie[now][i]]=true; } } } }; ACautomata AC; int main() { while(scanf("%d%d%d",&n,&m,&p)!=EOF) { memset(v,0,sizeof(v)); memset(trie[1],0,sizeof(trie[1])); tot=1; scanf("%s",ss); for(int i=0;i<n;i++) mp[ss[i]]=i; while(p--) { scanf("%s",s); AC.insert(); } AC.getfail(); bigint out=dfs(1,m); out.output(); puts(""); } }