DNA Sequence POJ - 2778 AC自动机构造矩阵
构建一个长度为n的串s,不能包含模板串,问一共多少种s
把所有病毒节点和以病毒节点为后缀的节点标为病毒节点
从编号i的节点走到j时,如果i,j都不是病毒节点,这样的走法才是安全的,mat[i][j]++
其他就是一些矩阵的知识了
#include<bits/stdc++.h> #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<iostream> #include<math.h> #include<set> #include<map> #include<vector> #include<iomanip> using namespace std; #define ll long long #define pb push_back #define FOR(a) for(int i=1;i<=a;i++) const int inf=0x3f3f3f3f; const int maxn=1e2+9; const int mod=1e5; const int sigma=4; struct Matrix{ ll mat[maxn][maxn]; int n; Matrix(){}; Matrix(int n1){n=n1;for(int i=0;i<n;i++)for(int j=0;j<n;j++)mat[i][j]=0;} Matrix operator *(const Matrix&b)const{ Matrix ret=Matrix(n); for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ for(int k=0;k<n;k++){ ret.mat[i][j]+=mat[i][k]*b.mat[k][j]; } ret.mat[i][j]%=mod; } } return ret; } }; Matrix matpow(Matrix mat,int n){ Matrix ret=Matrix(mat.n); for(int i=0;i<mat.n;i++)ret.mat[i][i]=1; while(n){ if(n&1)ret=ret*mat; mat=mat*mat; n=n>>1; } return ret; } int getindex(char x){ if(x=='A')return 0;if(x=='T')return 1; if(x=='C')return 2;return 3; } struct automata{ int ch[maxn][sigma]; int val[maxn]; int f[maxn]; int sz; int newnode(){ memset(ch[sz],0,sizeof(ch[sz])); f[sz]=val[sz]=0; return sz++; } void init(){ memset(val,0,sizeof(val)); sz=0; newnode(); } void insert(char *s,int v){ int u=0; int len=strlen(s); for(int i=0;i<len;i++){ int id=getindex(s[i]);//s[i]-'a'; if(!ch[u][id])ch[u][id]=newnode(); u=ch[u][id]; } val[u]++; } void build(){ queue<int>q; q.push(0); while(!q.empty()){ int u=q.front();q.pop(); if(val[f[u]]){ //当前字符串后缀是病毒,那这个也是病毒 //因为更新时先标浅层的单纯病毒串 val[u]++; } for(int i=0;i<sigma;i++){ int v=ch[u][i]; if(!v)ch[u][i]=ch[f[u]][i]; else q.push(v); if(u&&v)f[v]=ch[f[u]][i]; } } } void buildmat(Matrix &mat){ for(int i=0;i<sz;i++) for(int j=0;j<sigma;j++) if(!val[i] && !val[ch[i][j]]) mat.mat[i][ch[i][j]]++; } }ac; char s[20]; int main(){ int n,m; while(~scanf("%d%d",&m,&n)){ Matrix mat=Matrix(50); ac.init(); for(int i=0;i<m;i++){ scanf("%s",s); ac.insert(s,0); } ac.build(); ac.buildmat(mat); mat=matpow(mat,n); ll ans=0; for(int i=0;i<ac.sz;i++){ ans=(ans+mat.mat[0][i])%mod; } printf("%lld\n",ans); } }