HDU-2243 考研路茫茫——单词情结(AC自动机)
题目大意:给n个单词,长度不超过L的单词有多少个包含n个单词中的至少一个单词。
题目分析:用长度不超过L的单词书目减去长度在L之内所有不包含任何一个单词的书目。
代码如下:
# include<iostream> # include<cstdio> # include<queue> # include<cstring> # include<algorithm> using namespace std; # define LL long long # define ULL unsigned long long struct Matrix { int n; ULL ele[35][35]; Matrix(int _n):n(_n){ for(int i=0;i<n;++i) for(int j=0;j<n;++j) ele[i][j]=0; } }; int ch[35][26]; int fail[35],cnt; bool word[35]; void init() { cnt=0; memset(ch,-1,sizeof(ch)); memset(word,false,sizeof(word)); } int idx(char c) { return c-'a'; } void insert(char *s) { int n=strlen(s); int r=0; for(int i=0;i<n;++i){ int c=idx(s[i]); if(ch[r][c]==-1) ch[r][c]=++cnt; r=ch[r][c]; } word[r]=true; } void getFail() { queue<int>q; fail[0]=0; for(int i=0;i<26;++i){ if(ch[0][i]==-1){ ch[0][i]=0; }else{ fail[ch[0][i]]=0; q.push(ch[0][i]); } } while(!q.empty()) { int u=q.front(); q.pop(); if(word[fail[u]]) word[u]=true; for(int i=0;i<26;++i){ if(ch[u][i]==-1) ch[u][i]=ch[fail[u]][i]; else{ fail[ch[u][i]]=ch[fail[u]][i]; q.push(ch[u][i]); } } } } Matrix getMatrix() { Matrix mat(cnt+1); for(int i=0;i<mat.n;++i) for(int j=0;j<26;++j) if(!word[ch[i][j]]) ++mat.ele[i][ch[i][j]]; ++mat.n; for(int i=0;i<mat.n;++i){ mat.ele[mat.n-1][i]=0; mat.ele[i][mat.n-1]=1; } return mat; } Matrix mul(Matrix a,Matrix b) { Matrix c(a.n); for(int i=0;i<c.n;++i) for(int j=0;j<c.n;++j) for(int k=0;k<c.n;++k) c.ele[i][j]+=a.ele[i][k]*b.ele[k][j]; return c; } Matrix myPow(Matrix a,LL k) { Matrix mat(a.n); for(int i=0;i<mat.n;++i) mat.ele[i][i]=1; while(k>0){ if(k&1) mat=mul(mat,a); a=mul(a,a); k>>=1; } return mat; } ULL getSum(LL x) { Matrix mat(2); mat.ele[0][0]=26; mat.ele[0][1]=1; mat.ele[1][0]=0; mat.ele[1][1]=1; mat=myPow(mat,x); return mat.ele[0][1]; } char prefix[8]; int main() { int n; LL L; while(~scanf("%d%lld",&n,&L)) { init(); for(int i=0;i<n;++i){ scanf("%s",prefix); insert(prefix); } getFail(); Matrix mat=getMatrix(); mat=myPow(mat,L+1); ULL ans1=mat.ele[0][mat.n-1]; ULL ans2=getSum(L+1); cout<<ans2-ans1<<endl; } return 0; }