http://www.lydsy.com/JudgeOnline/problem.php?id=1030
AC自动机经典题型,数据不大,不用矩阵快速幂优化。
/* Footprints In The Blood Soaked Snow */ #include <cstdio> #include <cstring> #define cls(a, x) memset(a, x, sizeof(a)) using namespace std; const int maxn = 6005, maxm = 105, p = 10007, maxq = 10000; int dp[maxm][maxn], q[maxq]; struct _acm { int son[maxn][26], fail[maxn], acmcnt; bool flag[maxn]; void init() { cls(son, 0); for(int i = 0; i < maxn; i++) fail[i] = flag[i] = 0; acmcnt = 0; } void insert(char *s) { int now = 0, len = strlen(s); for(int i = 0; i < len; i++) { int &pos = son[now][s[i] - 'A']; if(!pos) pos = ++acmcnt; now = pos; } flag[now] = 1; } void getfail() { int h = 0, t = 0; for(int i = 0; i < 26; i++) if(son[0][i]) q[t++] = son[0][i]; while(h != t) { int u = q[h++]; for(int i = 0; i < 26; i++) if(!son[u][i]) son[u][i] = son[fail[u]][i]; else { fail[q[t++] = son[u][i]] = son[fail[u]][i]; flag[son[u][i]] |= flag[fail[son[u][i]]]; } } } } acm; inline int qpow(int a, int n) { int ans = 1; for(int t = a; n; n >>= 1, t = t * t % p) if(n & 1) ans = ans * t % p; return ans; } char str[maxm]; int main() { int n, m; scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) { scanf("%s", str); acm.insert(str); } acm.getfail(); dp[0][0] = 1; for(int i = 1; i <= m; i++) for(int j = 0; j <= acm.acmcnt; j++) for(int k = 0; k < 26; k++) if(!acm.flag[acm.son[j][k]]) dp[i][acm.son[j][k]] = (dp[i][acm.son[j][k]] + dp[i - 1][j]) % p; int ans = qpow(26, m); for(int i = 0; i <= acm.acmcnt; i++) ans = (ans - dp[m][i] + p) % p; printf("%d\n", ans); return 0; }