断断续续看了一周AC自动机和Trie图,总算明白一些了,A的不易啊
/* * ===================================================================================== * * Filename: 2778.cpp * Version: 1.0 * Created: 2013-08-25 00:26:31 * Revision: none * Compiler: GNU C++ * * Just like you,wait you forever~~ * * ===================================================================================== */ #include <set> #include <map> #include <list> #include <queue> #include <stack> #include <cmath> #include <string> #include <cstdio> #include <vector> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define PB push_back #define SIZE(x) (int)x.size() #define clr(x,y) memset(x,y,sizeof(x)) #define MP(x,y) make_pair(x,y) #define RS(n) scanf ("%s", n) #define ALL(t) (t).begin(),(t).end() #define FOR(i,n,m) for (int i = n; i <= m; i ++) #define ROF(i,n,m) for (int i = n; i >= m; i --) #define IT iterator #define FF first #define SS second typedef long long ll; typedef unsigned int uint; typedef unsigned long long ull; typedef vector<int> vint; typedef vector<string> vstring; typedef pair<int, int> PII; void RI (int& x){ x = 0; char c = getchar (); while (c == ' '||c == '\n') c = getchar (); bool flag = 1; if (c == '-'){ flag = 0; c = getchar (); } while (c >= '0' && c <= '9'){ x = x * 10 + c - '0'; c = getchar (); } if (!flag) x = -x; } void RII (int& x, int& y){RI (x), RI (y);} void RIII (int& x, int& y, int& z){RI (x), RI (y), RI (z);} /**************************************END define***************************************/ const ll mod = 100000; const ll LINF = 1e18; const int INF = 1e9; const double EPS = 1e-8; const int NODE = 105; const int CHD = 4; int code[255]; int chd[NODE][4], sz, fail[NODE], val[NODE]; void init (){ sz = 1; clr (chd[0], 0); } void insert (char* s){ int len = strlen (s); int p = 0; FOR (i, 0, len-1){ int c = code[s[i]]; if (!chd[p][c]){ clr (chd[sz], 0); chd[p][c] = sz ++; } p = chd[p][c]; } val[p] = 1; } void getfail (){ queue<int> q; FOR (i, 0, CHD-1){ fail[chd[0][i]] = 0; if (chd[0][i]){ q.push (chd[0][i]); } } while (SIZE (q)){ int node = q.front (); q.pop (); FOR (i, 0, CHD-1){ if (chd[node][i]){ int tmp = fail[node]; fail[chd[node][i]] = chd[tmp][i]; val[chd[node][i]] += val[chd[tmp][i]]; q.push (chd[node][i]); }else{ chd[node][i] = chd[fail[node]][i]; } } } } struct Mat{ ll a[105][105]; void initzero (){ clr (a, 0); } void initunit (){ FOR (i, 0, sz-1){ FOR (j, 0, sz-1){ a[i][j] = (i == j ? 1:0); } } } void modul (){ FOR (i, 0, sz-1){ FOR (j, 0, sz-1){ a[i][j] %= mod; } } } friend Mat operator * (Mat a, Mat b){ Mat ans; ans.initzero (); FOR (i, 0, sz-1){ FOR (j, 0, sz-1){ if (a.a[i][j]){ FOR (k, 0, sz-1){ ans.a[i][k] += a.a[i][j] * b.a[j][k]; } } } } ans.modul (); return ans; } friend Mat operator ^ (Mat a, int n){ Mat ans; ans.initunit (); while (n){ if (n&1){ ans = ans*a; } a = a*a; n >>= 1; } return ans; } }a; int main (){ init (); code['A'] = 0; code['T'] = 1; code['C'] = 2; code['G'] = 3; int n, len; RII (n, len); FOR (i, 1, n){ char s[15]; RS (s); insert (s); } getfail (); FOR (i, 0, sz-1){ if (!val[i]){ FOR (j, 0, CHD-1){ int v = chd[i][j]; if (!val[v]){ a.a[v][i] ++; } } } } a = a^len; ll ans = 0; FOR (i, 0, sz-1){ ans = (ans + a.a[i][0]) % mod; } cout << ans << endl; }