分析:与poj的2778差不多的,求出来所有的情况然后减去不包含的就行了,这次使用了一下kuangbin的那种自动机写法,确实还不错,因为尤是在建立矩阵的时候更加方便。
代码如下:
===============================================================================================================================
#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> #include<iostream> using namespace std; const int MAXN = 107; const int MAXM = 26; const int mod = 100000; struct Matrix {///定义矩阵 int size; unsigned long long edge[MAXN][MAXN]; Matrix(int Len) { size = Len; memset(edge, false, sizeof(edge)); } Matrix operator *(const Matrix &Map) const { Matrix ans(size); for(int i=0; i<size; i++) for(int j=0; j<size; j++) for(int k=0; k<size; k++) { ans.edge[i][j] += edge[i][k] * Map.edge[k][j]; } return ans; } }; struct Ac_Trie { int next[MAXN][MAXM]; int fail[MAXN], End[MAXN]; int Len, root; Ac_Trie() { memset(next, -1, sizeof(next)); memset(End, false, sizeof(End)); Len = 1, root = 0; } void Insert(char s[]) { int p = root; for(int i=0; s[i]; i++) { int k = s[i] - 'a'; if(next[p][k] == -1) next[p][k] = Len++; p = next[p][k]; } End[p] = true; } void GetFail() { queue<int> Q; int p = root; fail[p] = root; for(int i=0; i<MAXM; i++) { if(next[p][i] == -1) next[p][i] = root; else { fail[next[p][i]] = root; Q.push(next[p][i]); } } while(Q.size()) { p = Q.front(); Q.pop(); for(int i=0; i<MAXM; i++) { if(next[p][i] == -1) next[p][i] = next[fail[p]][i]; else { fail[next[p][i]] = next[fail[p]][i]; Q.push(next[p][i]); } } End[p] |= End[fail[p]]; } } Matrix GetMatrix() { Matrix ans(Len+1); for(int i=0; i<Len; i++) for(int k=0; k<MAXM; k++) { if(End[next[i][k]] == false) ans.edge[i][next[i][k]] += 1; } for(int i=0; i<=Len; i++) ans.edge[i][Len] = 1; return ans; } }; Matrix QuickPow(long long K, Matrix Map) { Matrix ans(Map.size); for(int i=0; i<ans.size; i++) ans.edge[i][i] = 1; while(K) { if(K & 1) ans = ans * Map; Map = Map * Map; K /= 2; } return ans; } int main() { long long N, L; while(scanf("%lld%lld", &N, &L) != EOF) { char s[MAXN]; Ac_Trie a; while(N--) { scanf("%s", s); a.Insert(s); } a.GetFail(); Matrix ans = a.GetMatrix(); unsigned long long sum1=0, sum=0; ans = QuickPow(L, ans); for(int i=0; i<ans.size; i++) sum1 += ans.edge[0][i]; ans.size = 2; ans.edge[0][0] = 26; ans.edge[1][0] = 0; ans.edge[0][1] = ans.edge[1][1] = 1; ans = QuickPow(L, ans); sum = ans.edge[0][1] + ans.edge[0][0]; cout << sum - sum1 <<endl; } return 0; }