刷AC自动机,很久以前做过,再系统地做一便,发现之前dp矩阵的裸体都过不了。玄学修改后就行了(板子问题???)
记录一下
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define ll long long
int ch[105][5];
int root = 0;
ll mod = (ll)1e5;
int fail[105], val[105], sz;
char rea[4] = {'A', 'T', 'C', 'G'};
int react(char c)
{
if (c == 'A')
return 0;
if (c == 'T')
return 1;
if (c == 'C')
return 2;
if (c == 'G')
return 3;
}
void init()
{
sz = 0;
root = 0;
val[0] = 0;
for (int i = 0; i <= 3; i++)
ch[root][i] = root;
}
int newnode()
{
sz++;
val[sz] = 0;
for (int i = 0; i < 4; i++)
ch[sz][i] = 0;
return sz;
}
void build(char buf[])
{
int cur = root;
int len = strlen(buf);
for (int i = 0; i < len; i++)
{
int c = react(buf[i]);
if (ch[cur][c] == root)
{
int u = newnode();
ch[cur][c] = u;
}
cur = ch[cur][c];
}
val[cur] = 1;
}
void getfail()
{
int cur = root;
queue<int> q;
for (int i = 0; i <= 3; i++)
{
if (ch[root][i] == root)
{
continue;
}
int u = ch[root][i];
fail[u] = root;
q.push(u);
}
while (!q.empty())
{
int u = q.front();
q.pop();
val[u] |= val[fail[u]];
for (int i = 0; i <= 3; i++)
{
int v = ch[u][i];
if (v == root)
{
ch[u][i] = ch[fail[u]][i];
continue;
}
fail[v] = ch[fail[u]][i];
q.push(v);
}
}
}
struct matrix
{
ll a[105][105];
matrix()
{
for (int i = 0; i <= sz; i++)
for (int j = 0; j <= sz; j++)
a[i][j] = 0;
}
ll* operator [] (int i)
{
return a[i];
}
};
matrix base;
matrix mult(matrix a, matrix b)
{
matrix ans;
for (int i = 0; i <= sz; i++)
{
for (int j = 0; j <= sz; j++)
{
for (int k = 0; k <= sz; k++)
{
ans[i][j] += a[i][k] * b[k][j] % mod;
ans[i][j] %= mod;
}
}
}
return ans;
}
void get_base()
{
for (int cur = root; cur <= sz; cur++)
{
if (val[cur])
continue;
for (int i = 0; i <= 3; i++)
{
if (val[ch[cur][i]])
continue;
base[cur][ch[cur][i]]++;
}
}
}
template<class T>
void read(T& ret)
{
ret = 0;
char c;
while ((c = getchar()) > '9' || c < '0');
while (c >= '0' && c <= '9')
{
ret = ret * 10 + c - '0';
c = getchar();
}
}
char s[100];
int main()
{
int m;
ll n;
read(m), read(n);
init();
for (int i = 1; i <= m; i++)
{
scanf("%s", s);
build(s);
}
getfail();
matrix ans;
for (int i = 0; i <= sz; i++)
ans[i][i] = 1;
get_base();
while (n)
{
if (n & 1)
ans = mult(ans, base);
base = mult(base, base);
n >>= 1;
}
ll sum = 0;
for (int i = 0; i <= sz; i++)
sum = (sum + ans[0][i]) % mod;
printf("%lld\n", sum);
return 0;
}