2 3aa ab1 2a
10452
通过求出所有可能数(26+26^1+...+26^n) - 不包含模式串各个长度总数来得到结果
求出可行矩阵A,求出A+A^1+...+A^n(记作S^n),则:
S^n=S^k * (E+A^k)+A^n // n=2*k+1
=S^k * (E+A^k) //n=2*k
这就是递归一样,我们可以从下到上类似栈一样来实现(代码)
源代码:
#include<iostream> using namespace std; const int KIND=26; const int MAX=35; struct TrieNode { bool unsafe; int index; TrieNode *fail; TrieNode *next[KIND]; }; TrieNode memory[MAX]; int allocp; TrieNode *q[MAX]; int m; __int64 n; TrieNode *CreateTrieNode() { TrieNode *p=&memory[allocp]; p->unsafe=false; p->index=allocp; allocp++; p->fail=NULL; memset(p->next,0,sizeof(p->next)); return p; } void InsertTrieNode(TrieNode *pRoot,char s[]) { TrieNode *p=pRoot; int i=0; while(s[i]) { int k=s[i]-'a'; if(p->next[k]==NULL) p->next[k]=CreateTrieNode(); i++; p=p->next[k]; } p->unsafe=true; } void Build_AC_Automation(TrieNode *pRoot) { int head=0,tail=0,i; TrieNode *p; q[tail++]=pRoot; pRoot->fail=NULL; while(head!=tail) { p=q[head++]; for(i=0;i<KIND;i++) if(p->next[i]!=NULL) { if(p==pRoot) p->next[i]->fail=pRoot; else { p->next[i]->fail=p->fail->next[i]; if(p->next[i]->fail->unsafe) p->next[i]->unsafe=true; } q[tail++]=p->next[i]; } else { if(p==pRoot) p->next[i]=pRoot; else p->next[i]=p->fail->next[i]; } } } struct Matrix { unsigned __int64 a[MAX][MAX]; int sz; }; Matrix E; void InitE(int size) //初始化单位矩阵 { E.sz=size; for(int i=0;i<E.sz;i++) for(int j=0;j<E.sz;j++) E.a[i][j]=(i==j); } Matrix MatrixAdd(Matrix m1,Matrix m2)//两矩阵再加 { for(int i=0;i<m1.sz;i++) for(int j=0;j<m2.sz;j++) m1.a[i][j] += m2.a[i][j]; return m1; } Matrix MatrixMul(Matrix a,Matrix b)//两矩阵相乘 { Matrix c; int i,j,k; c.sz=a.sz; for(i=0;i<c.sz;i++) for(j=0;j<c.sz;j++) { c.a[i][j]=0; for(k=0;k<c.sz;k++) c.a[i][j] += a.a[i][k]*b.a[k][j]; } return c; } Matrix MatrixPow(Matrix a,__int64 n)//矩阵的n次幂 { Matrix t=E; while(n>0) { if(1&n) t=MatrixMul(t,a); a=MatrixMul(a,a); n >>= 1; } return t; } Matrix MatrixSum(Matrix m0,__int64 times)//矩阵幂求和 { Matrix m1,m2; m1=m2=m0; int i,bin[65],n=0; while(times>0) { bin[n++]=(times&1); times >>= 1; } for(i=n-2;i>=0;i--)//bin[n-1]一定为1 { m1=MatrixMul(m1,MatrixAdd(m2,E)); m2=MatrixMul(m2,m2); if(bin[i]) { m2=MatrixMul(m2,m0); m1=MatrixAdd(m1,m2); } } return m1; } int main() { int i,j; char word[15]; TrieNode *pRoot; while(scanf("%d%I64d",&m,&n)!=EOF) { allocp=0; pRoot=CreateTrieNode(); for(i=0;i<m;i++) { scanf("%s",word); InsertTrieNode(pRoot,word); } Build_AC_Automation(pRoot); Matrix g,dp; InitE(allocp); //初始化单位阵 g.sz=allocp; //初始化g for(i=0;i<g.sz;i++) for(j=0;j<g.sz;j++) g.a[i][j]=0; for(i=0;i<allocp;i++) //构建矩阵 for(j=0;j<KIND;j++) { TrieNode *tmp=memory[i].next[j]; if(memory[i].unsafe==false && tmp->unsafe==false)//要安全的 g.a[i][tmp->index]++; } g=MatrixSum(g,n); unsigned __int64 ans=0; for(i=0;i<allocp;i++) ans += g.a[0][i]; //下面计算26+26^1+......+26^n dp.sz=1; dp.a[0][0]=26; dp=MatrixSum(dp,n); printf("%I64u\n",dp.a[0][0]-ans); } return 0; }