#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
int n,l,sz;
int ch[40][26],f[40],last[40],value[40];
long long map[40][40];
void insert (char c[]){
int i = 0;
int len = strlen(c);
for(int j = 0; j < len; j++){
int index = c[j]-'a';
if(!ch[i][index]){
memset(ch[sz], 0, sizeof(ch[sz]));
ch[i][index] = sz;
sz++;
}
i = ch[i][index];
}
value[i] = 1;
}
void fail (){
queue<int> q;
for(int i = 0; i < 26; i++){
if(ch[0][i]) {f[ch[0][i]] = 0; q.push(ch[0][i]);}
}
while (!q.empty()) {
int u = q.front();
q.pop();
for(int i = 0; i < 26; i++){
if (ch[u][i]) {
int x = ch[u][i];
int y = f[u];
while(y && !ch[y][i]) y = f[y];
f[x] = ch[y][i];
last[x] = (value[f[x]]==1 ? f[x] : last[f[x]]);
q.push(x);
}
}
}
}
void init (){
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
memset(f, 0, sizeof(f));
memset(last, 0, sizeof(last));
memset(value, 0, sizeof(value));
memset(map, 0, sizeof(map));
for(int i = 0; i < n; i++){
char c[6];
scanf("%s", c);
insert(c);
}
fail();
}
void makemap (){
for(int i = 0; i < sz; i++){
if (value[i]==1) {
continue;
}
for(int j = 0; j < 26; j++){
int u = i;
while (u && !ch[u][j]) u = f[u];
u = ch[u][j];
int p = (value[u]==1 ? u : last[u]);
// while(p){
// if(value[p]==1) break;
// p = f[p];
// }
if(p==0) map[i][u]++;
}
}
}
void add (long long a[][40], long long b[][40]){
for(int i = 0; i < sz; i++){
for(int j = 0; j < sz; j++){
a[i][j] += b[i][j];
}
}
}
void mul(long long a[][40], long long b[][40]){
long long temp[40][40];
for(int i = 0; i < sz; i++){
for(int j = 0; j < sz; j++) {
temp[i][j] = 0;
for(int k = 0; k < sz; k++) temp[i][j] += a[i][k]*b[k][j];
}
}
memcpy(a, temp, sizeof(map));
}
void pow (long long a[][40], long long b[][40], int k){
memset(a, 0, sizeof(map));
for(int i = 0; i < sz; i++) a[i][i] = 1;
long long mm[40][40];
memcpy(mm,b,sizeof(map));
while (k) {
if (k%2==1) {
mul(a, mm);
}
mul(mm, mm);
k = k/2;
}
}
void pow_sum (long long a[][40], long long b[][40], int k){
if (k==1) {
memcpy(a, b, sizeof(map));
return;
}
long long c[40][40];
long long d[40][40];
memset(a, 0, sizeof(map));
pow_sum(a, b, k>>1);
pow(c, b, k>>1);
memcpy(d, a, sizeof(map));
mul(d, c);
add(a, d);
if (k%2==1) {
mul(c, c);
mul(c, b);
add(a, c);
}
}
int main(int argc, const char * argv[])
{
while (scanf("%d%d",&n,&l)!=EOF) {
init();
makemap();
long long result[40][40];
pow_sum(result, map, l);
long long ret = 0;
for(int i =0; i < sz; i++) ret -= result[0][i];
map[0][0] = 26;
sz = 1;
pow_sum(result, map, l);
ret += result[0][0];
printf("%I64u\n",ret);
//printf("%lld\n",ret);
}
}
HDOJ 2243 考研路茫茫——单词情结 AC自动机+矩阵快速求幂和
最新推荐文章于 2024-05-20 20:08:58 发布