看到L那么大就应该想到矩阵快速幂。
而且这道题和之前的POJ 2778. DNA Sequence很想。
我们只需要计算一下长度小于等于n的不包含特殊串的个数(矩阵中要增加一维代表每一行的sum),然后用总的可能数减去不包含的就是答案了(总的可能数很多人都是用矩阵写的,其实用等比数列求和公式就行了啊)。
#include<bits/stdc++.h>
using namespace std;
char ss[10];
struct AC{
int nex[100][26], root, tot;
int f[100], ed[100];
int newnode() {
for(int i = 0; i < 26; i++) {
nex[tot][i] = -1;
}
ed[tot] = 0;
return tot++;
}
void init() {
tot = 0;
root = newnode();
}
void insert(char *s) {
int u = root, L = strlen(s);
for(int i = 0; i < L; i++) {
int ch = s[i]-'a';
if(nex[u][ch] == -1) nex[u][ch] = newnode();
u = nex[u][ch];
}
ed[u] = 1;
}
void getfail() {
queue<int>Q;
for(int i = 0; i < 26; i++) {
if(nex[root][i] == -1) nex[root][i] = root;
else {
f[nex[root][i]] = root;
Q.push(nex[root][i]);
}
}
while(!Q.empty()) {
int u = Q.front();Q.pop();
ed[u] |= ed[f[u]];
for(int i = 0; i < 26; i++) {
if(nex[u][i] == -1) nex[u][i] = nex[f[u]][i];
else {
f[nex[u][i]] = nex[f[u]][i];
Q.push(nex[u][i]);
}
}
}
}
}ac;
typedef unsigned long long ull;
class matrix{
public:
ull a[105][105];
int n, m;
matrix(int n, int m) {
this->n = n;
this->m = m;
memset(a, 0, sizeof(a));
}
matrix operator *(matrix &b) {
matrix c(n, b.m);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= b.m; j++) {
for(int k = 1; k <= m; k++) {
c.a[i][j] += a[i][k] * b.a[k][j];
}
}
}
return c;
}
matrix pow(int x) {
matrix res(n, n), A(n, n);
for(int i = 1; i <= n; i++) res.a[i][i] = 1;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
A.a[i][j] = a[i][j];
}
}
while(x) {
if(x&1) res = res*A;
A = A*A;
x >>= 1;
}
return res;
}
};
ull power(ull n, ull s) {
ull res = 1;
while(n) {
if(n&1) res = res*s;
s = s*s;
n = n>>1;
}
return res;
}
int main() {
int n, m;
while(scanf("%d%d", &n, &m) == 2) {
ac.init();
for(int i = 1; i <= n; i++) {
scanf("%s", ss);
ac.insert(ss);
}
ac.getfail();
matrix A(ac.tot+1, ac.tot+1);
for(int j = 0; j < ac.tot; j++) {
for(int k = 0; k < 26; k++) {
int u = ac.nex[j][k];
if(!ac.ed[u]) {A.a[j+1][u+1]++;}
}
}
for(int i = 0; i <= ac.tot; i++) A.a[i+1][ac.tot+1] = 1;
A = A.pow(m);
ull res1 = (power(m+1, 26)-26)*power((1ll<<63)-1, 25);
ull res2 = 0;
for(int i = 0; i <= ac.tot; i++) res2 += A.a[1][i+1];
printf("%llu\n", res1-res2+1);
}
}