程序未对矩阵进行压缩时间是766ms,进行压缩后是32ms
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include<queue>
using namespace std;
typedef long long LL;
const int SN = 4;
const int MN = 105;
int N = MN;
const int M = 100000;
struct Matrix{
int v[MN][MN];
Matrix(){memset(v,0,sizeof(v));}
Matrix(int){
Matrix();
for(int i = 0; i < N; ++i)v[i][i] = 1;
}
}a;
//struct queue{
// int top,rear;
// int a[N];
// queue(){top = rear = 0;}
// int front(){return a[top++];}
// bool empty(){return top == rear;}
// void push(int k){a[rear++] = k;}
//};
Matrix operator *(const Matrix &a,const Matrix &b){
Matrix c;
long long v;
for(int i = 0; i < N; ++i)
for(int j = 0;j < N; ++j){
v = 0;
for(int k = 0; k < N; ++k)
v += (LL)a.v[i][k]*b.v[k][j];
if(v >= M)v %= M;
c.v[i][j] = (int) v;
}
return c;
}
//Matrix operator % (Matrix a,const int m){
// for(int i = 0; i < N; ++i)
// for(int j = 0;j < N; ++j)
// a.v[i][j] %= M;
// return a;
//}
//Matrix operator ^(Matrix a,int b){
// if(b == 1) return a;
// Matrix c = (a^(b>>1));
// if(b&1) return c*c*a;
// return c*c;
//}
Matrix operator^(Matrix a,long long b){
Matrix c(0);
while(b){
if(b&1) c = c*a;
a = a*a;
b >>= 1;
}
return c;
}
long long getsumoffirstline(Matrix a){
long long sum = 0;
for(int i = 0;i < N; ++i) sum += a.v[0][i];
return sum % M;
}
class AAM{
public:
int ch[MN][SN],tag[MN],fail[MN];
int root,cnt;
int id['Z'];
void init(){
cnt = 0,root = cnt++;
id['A'] = 0;
id['T'] = 1;
id['G'] = 2;
id['C'] = 3;
memset(ch[0],0,sizeof(ch[0]));
memset(tag,0,sizeof(tag));
memset(fail,0,sizeof(fail));
}
void insert(char *s){
int p = root;
while(*s){
int index = id[*s];
if(tag[p]) return;//小小的优化
if(!ch[p][index]){
ch[p][index] = cnt;
memset(ch[cnt],0,sizeof(ch[cnt]));
++cnt;
}
p = ch[p][index];
s++;
}
tag[p] = 1;
}
void getfail(){
queue<int> Q;
for(int i = 0; i < SN; ++i){//两个数组都有清零不用再赋0给他了
if(ch[0][i]){
Q.push(ch[0][i]);
}
}
while(!Q.empty()){
int u = Q.front();Q.pop();
if(tag[fail[u]]) tag[u] = 1;
for(int i = 0;i < SN; ++i){
int &v = ch[u][i];
if(v){
fail[v] = ch[fail[u]][i];
Q.push(v);
}else v = ch[fail[u]][i];
}
}
}
void getMatrix(){
Matrix c;
int cnt1,cnt2;
for(int i = 0; i < cnt; ++i)
for(int j = 0; j < SN; ++j)
if(!tag[i] && !tag[ch[i][j]]){
a.v[i][ch[i][j]] ++;
}
for(int i = 0; i < cnt; ++i){ //压缩行列
cnt1 = 0;
for(int j = 0; j < cnt; ++j){
if(!tag[j]){
a.v[i][cnt1++] = a.v[i][j];
}
}
}
for(int i = 0; i < cnt; ++i){
cnt1 = 0;
for(int j = 0; j < cnt; ++j){
if(!tag[j]){
a.v[cnt1++][i] = a.v[j][i];
}
}
}
N = cnt1;
}
};
char s[15];
long long n,m;
AAM T;
int main()
{
T.init();
scanf("%lld%lld",&m,&n);
while(m--){
scanf("%s",s);
T.insert(s);
}
T.getfail();
T.getMatrix();
printf("%lld\n",getsumoffirstline(a^n));
return 0;
}