四种状态A T C G,对于每个病毒串插入时的最后一个字符标记为1,表示该串不能出现!(trie字典树)
建立fail数组,对于没有出现的状态都归于0状态,建立AC自动机fail指针时顺带记录当前串的后缀是否是病毒
所有东西处理完之后根据每个串的状态去建邻接矩阵
之后就是我们最喜欢的矩阵快速幂了
#include <iostream> #include <cstdio> #include <sstream> #include <cstring> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> #include <cmath> using namespace std; #define ll long long #define re register const int N=1e6+10; const int mod=1e5; void read(int &a) { a=0;int d=1;char ch; while(ch=getchar(),ch>'9'||ch<'0') if(ch=='-') d=-1; a=ch^48; while(ch=getchar(),ch>='0'&&ch<='9') a=(a<<3)+(a<<1)+(ch^48); a*=d; } struct note{int nex,to[5],bz;}trie[N]; char s[N]; struct node{int a[105][105];}ans,a; int cnt=0; map <char,int> vis; void init(){vis['A']=0;vis['C']=1;vis['G']=2;vis['T']=3;} void ins() { int len=strlen(s),now=0; for(re int i=0;i<len;i++) { int x=vis[s[i]]; if(!trie[now].to[x]) trie[now].to[x]=++cnt; now=trie[now].to[x]; } trie[now].bz=1; } void build() { queue <int> q; for(re int i=0;i<4;i++) if(trie[0].to[i]) trie[trie[0].to[i]].nex=0,q.push(trie[0].to[i]); while(!q.empty()) { int p=q.front();q.pop(); for(re int i=0;i<4;i++) { if(trie[p].to[i]) q.push(trie[p].to[i]),trie[trie[p].to[i]].nex=trie[trie[p].nex].to[i]; else trie[p].to[i]=trie[trie[p].nex].to[i]; trie[trie[p].to[i]].bz|=trie[trie[trie[p].nex].to[i]].bz; } } } void built() { for(re int i=0;i<=cnt;i++) for(re int j=0;j<4;j++) if(!trie[i].bz&&!trie[trie[i].to[j]].bz) a.a[i][trie[i].to[j]]++; } node mul(node x,node y) { node c; for(re int i=0;i<=cnt;i++) { for(re int j=0;j<=cnt;j++) { c.a[i][j]=0; for(re int k=0;k<=cnt;k++) c.a[i][j]=(c.a[i][j]+1ll*x.a[i][k]*y.a[k][j]%mod)%mod; } } return c; } node quickmod(node x,int y) { node res,base=x; for(re int i=0;i<=cnt;i++) for(re int j=0;j<=cnt;j++) res.a[i][j]=i==j?1:0; while(y) { if(y&1) res=mul(res,base); base=mul(base,base); y>>=1; } return res; } int main() { init(); int m,n; read(m),read(n); while(m--) { scanf("%s",&s); ins(); } for(re int i=0;i<=cnt;i++) for(re int j=0;j<=cnt;j++) a.a[i][j]=0; build();built(); ans=quickmod(a,n); int answer=0; for(re int i=0;i<=cnt;i++) answer=(answer+ans.a[0][i])%mod; printf("%d",answer); return 0; }