Meaning of the questions: give some viruses string length you ask consisting of n ATGC to these viruses do not contain the number of how many strings
analysis:
We first analyze the structure Tire chart: Trie FIG is to add on the prototype AC automatic machine side so that the state can be quickly transferred, labeled hazardous node (suffix node defective word); then we want configured length n does not comprise bad string right, it is not the number of programs in FIG trie n steps away from the secure node to node 0 (FIG Trie are state transition diagrams)
In a directed graph, A k-step walk to the number of Scheme B (which is obviously a classic matrix fast power issues), (principle needs its own search) to build a picture of the adjacent table M [i] [j], M [i] [j] = 1 i to j represents bordered directly connected, then ans = pow (M, k), ans [A] [B] as an answer
#include<queue> #include<stdio.h> #include<string.h> using namespace std; const int Max_Tot = 1e2 + 10; const int Letter = 4; const int MOD = 1e5; int maxn; int mp[128]; struct mat{ int m[111][111]; }unit, M; mat operator * (mat a, mat b) { mat ret; long long x; for(int i=0; i<maxn; i++){ for(int j=0; j<maxn; j++){ x = 0; for(int k=0; k<maxn; k++){ x += (long long)a.m[i][k]*b.m[k][j]; } ret.m[i][j] = x % MOD; } } return ret; } inline void init_unit() { for(int i=0; i<maxn; i++) unit.m[i][i] = 1; } mat pow_mat(mat a, int n) { mat ret = unit; while(n){ if(n&1) ret = ret * a; a = a*a; n >>= 1; } return ret; } struct Aho{ struct StateTable{ int Next[Letter]; int fail, flag; }Node[Max_Tot]; int Size; queue<int> que; inline void init(){ while(!que.empty()) que.pop(); memset(Node[0].Next, 0, sizeof(Node[0].Next)); Node[0].fail = Node[0].flag = 0; Size = 1; } inline void insert(char *s){ int now = 0; for(int i=0; s[i]; i++){ int idx = mp[s[i]]; if(!Node[now].Next[idx]){ memset(Node[Size].Next, 0, sizeof(Node[Size].Next)); Node[Size].fail = Node[Size].flag = 0; Node[now].Next[idx] = Size++; } now = Node[now].Next[idx]; } Node[now].flag = 1; } //1) If the Son [i] does not exist, it is now pointing to the current node pointer points fail // the successor node number i (guaranteed been calculated). // 2) If Son [i] is present, it will fail fail pointer to the current node is now // pointer to the successor node number i (guaranteed been calculated). inline void BuildFail () { the Node [ 0 ] .fail = 0 ; for ( int I = 0 ; I <Letter; I ++ ) { IF (the Node [ 0 ] .NEXT [I]) { the Node [the Node [ 0 ] .NEXT [I]] = Fail. 0 ; que.push (the Node [ 0 ] .NEXT [I]); } the else the Node [0].Next[i] = 0;///必定指向根节点 } while(!que.empty()){ int top = que.front(); que.pop(); if(Node[Node[top].fail].flag) Node[top].flag = 1; for(int i=0; i<Letter; i++){ int &v = Node[top].Next[i]; if(v){ que.push(v); Node[v].fail = Node[Node[top].fail].Next[i]; }else v = Node[Node[top].fail].Next[i]; } } } inline void BuildMatrix(){ for(int i=0; i<Size; i++) for(int j=0; j<Size; j++) M.m[i][j] = 0; for(int i=0; i<Size; i++){ for(int j=0; j<Letter; j++){ if(!Node[i].flag && !Node[ Node[i].Next[j] ].flag) M.m[i][Node[i].Next[j]]++; } } maxn = Size; } }ac; char S[11]; int main(void) { mp['A']=0, mp['T']=1, mp['G']=2, mp['C']=3; int n, m; while(~scanf("%d %d", &m, &n)){ ac.init(); for(int i=0; i<m; i++){ scanf("%s", S); ac.insert(S); } ac.BuildFail(); ac.BuildMatrix(); // for(int i=0; i<10; i++){ // for(int j=0; j<10; j++){ // printf("%d ", M.m[i][j]); // }puts(""); // }puts(""); init_unit(); M = pow_mat(M, n); // for(int i=0; i<10; i++){ // for(int j=0; j<10; j++){ // printf("%d ", M.m[i][j]); // }puts(""); // }puts(""); int ans = 0; for(int i=0; i<ac.Size; i++) ans += M.m[0][i]; ans %= MOD; printf("%d\n", ans); } return 0; }