分析

仍然考虑 。我们考虑这个串是否可行,主要看是否经过了一个 的节点。那么我们定义 表示考虑前 长的串,现在到了 节点,合法,不合法的个数分别有多少个。那么转移就暴力转移了,因为 都很小。那么总的复杂度为

代码

#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 100,mod = 1e4 + 7;
int f[110][N][2],fail[N],ch[N][26],val[N],size;
int n,m;
void insert(char *S) {
    int len = strlen(S + 1),u = 0;
    for(int i = 1;i <= len;i++) {
        int c = (S[i] - 'A');
        if(!ch[u][c]) ch[u][c] = ++size;
        u = ch[u][c];
    }val[u] |= 1;
}
void build() {
    queue<int> Q;
    for(int i = 0;i < 26;i++) if(ch[0][i]) Q.push(ch[0][i]);
    while(!Q.empty()) {
        int x = Q.front();Q.pop();
        for(int i = 0;i < 26;i++) {
            int y = ch[x][i];
            if(y) {fail[ch[x][i]] = ch[fail[x]][i];val[y] |= val[fail[y]];Q.push(y);}
            else ch[x][i] = ch[fail[x]][i];
        }
    }
}
void inc(int &x,int y) {x = (x + y) % mod;}
int main() {
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i++) {
        static char S[N];scanf("%s",S + 1);insert(S);
    }
    build();
    f[0][0][0] = 1;
    for(int i = 0;i < m;i++) {
        for(int j = 0;j <= size;j++) {
            if(val[j]) inc(f[i][j][1],f[i][j][0]),f[i][j][0] = 0; 
            for(int k = 0;k < 26;k++) {
                inc(f[i + 1][ch[j][k]][0],f[i][j][0]);
                inc(f[i + 1][ch[j][k]][1],f[i][j][1]);
            }
        }
    }
    int ans = 0;
    for(int i = 0;i <= size;i++) {
        if(val[i]) inc(f[m][i][1],f[m][i][0]),f[m][i][0] = 0;
        inc(ans,f[m][i][1]);
    }
    cout << ans << endl;return 0;
}