求不包含模式串的文本串个数,n极大。我们还是类似的建出ACAM,然后在上面跑dp,只不过这次我们要矩阵倍增来加速。复杂度 O((m∗len)3logn)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define N 110
#define inf 0x3f3f3f3f
#define mod 100000
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
char s[30];
int n=0,K,m,rt,son[N][4],fail[N],end[N],id[300],ans=0;
struct Matrix{
int a[N][N];
Matrix(){}
Matrix(bool flag){
memset(a,0,sizeof(a));
if(flag) for(int i=1;i<=n;++i) a[i][i]=1;
}friend Matrix operator*(Matrix a,Matrix b){
Matrix res(0);
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
for(int k=1;k<=n;++k)
res.a[i][j]=(res.a[i][j]+(ll)a.a[i][k]*b.a[k][j])%mod;
return res;
}friend Matrix operator^(Matrix a,int k){
Matrix res(1);
for(;k;k>>=1,a=a*a)
if(k&1) res=res*a;return res;
}
}a,b;
inline void ins(char *s){
int len=strlen(s+1),p=rt;
for(int i=1;i<=len;++i){
int &y=son[p][id[s[i]]];if(!y) y=++n;p=y;
}end[p]=1;
}
inline void buildAC(){
queue<int>q;q.push(rt);
while(!q.empty()){
int x=q.front();q.pop();
for(int i=0;i<4;++i){
int &y=son[x][i];
if(!y){y=son[fail[x]][i];continue;}q.push(y);
fail[y]=son[fail[x]][i];end[y]|=end[fail[y]];
}
}
}
int main(){
// freopen("a.in","r",stdin);
m=read();K=read();rt=++n;id['A']=0;id['T']=1;id['C']=2;id['G']=3;
for(int i=0;i<4;++i) son[0][i]=rt;
for(int i=1;i<=m;++i) scanf("%s",s+1),ins(s);buildAC();
for(int i=1;i<=n;++i)
for(int j=0;j<4;++j)
if(!end[i]&&!end[son[i][j]]) a.a[i][son[i][j]]++;
a=a^K;
for(int i=1;i<=n;++i)
if(!end[i]) ans=(ans+a.a[1][i])%mod;
printf("%d\n",ans);
return 0;
}