Title Link: http://poj.org/problem?id=2778
Test instructions: There is a disease in the M DNA sequence, asking how many DNA sequences of length n do not contain any kind of disease-containing DNA sequences. (A,t,c,g four characters only)
Idea: Trie diagram of the state transfer, with the Matrix Mat[i][j] to represent from the node I to J only walk one step there are several ways, then the n power of the mat from the node I to J Walk N steps there are several ways to solve the problem is to go from the head node N step and do not contain dangerous nodes of the walk method.
Mat = mat^n ans = (mat[0][0] + mat[0][1] + ... + mat[0][num]) num is the number of nodes
Code
1#include <cstdio>2#include <cstring>3#include <queue>4#include <map>5 using namespacestd;6 Const intKIND =4;7 Const intMAXN = the;8 Const intMOD =100000;9typedefLong LongLL;Ten One structTrie A { - intNext[maxn][kind], FAIL[MAXN]; - BOOLISEXIT[MAXN]; the introot, L; -map<Char,int>MP; - LL MAT[MAXN][MAXN]; - LL RET[MAXN][MAXN]; + LL TMP[MAXN][MAXN]; - intCreate () + { A for(inti =0; i < KIND; ++i) atNext[l][i] =-1; -isexit[l++] =false; - returnL1; - } - voidInit () - { inL =0; -Root =Create (); tomp['A'] =0; +mp['C'] =1; -mp['G'] =2; themp['T'] =3; *Memset (Mat,0,sizeof(MAT)); $memset (ret,0,sizeof(ret));Panax Notoginseng } - voidInsertCharstr[]) the { + intnow =Root; A intLen =strlen (str); the for(inti =0; i < Len; ++i) + { - if(-1==Next[now][mp[str[i]]) $Next[now][mp[str[i]] =Create (); $now =Next[now][mp[str[i]]; - } -Isexit[now] =true; the } - voidbuild ()Wuyi { thequeue<int>Q; - for(inti =0; i < KIND; ++i) Wu { - if(-1==Next[root][i]) AboutNext[root][i] =Root; $ Else - { -Fail[next[root][i]] =Root; - Q.push (Next[root][i]); A } + } the while(!q.empty ()) - { $ intnow =Q.front (); the Q.pop (); the if(Isexit[fail[now]]) theIsexit[now] =true; the for(inti =0; i < KIND; ++i) - { in if(-1==Next[now][i]) theNext[now][i] =Next[fail[now]][i]; the Else About { theFail[next[now][i]] =Next[fail[now]][i]; the Q.push (Next[now][i]); the } + } - } the }Bayi voidGetmatrix () the { the for(inti =0; i < L; ++i) - { - for(intj =0; J < KIND; ++j) the { the if(!Isexit[next[i][j]]) the++Mat[i][next[i][j]]; the } - } the } the voidMatrixmul (ll MAT1[MAXN][MAXN], LL MAT2[MAXN][MAXN]) the {94 LL MAT3[MAXN][MAXN]; the for(inti =0; i < L; ++i) the { the for(intj =0; J < L; ++j)98 { AboutMAT3[I][J] =0; - for(intK =0; K < L; ++k)101MAT3[I][J] = (Mat3[i][j] + mat1[i][k] * mat2[k][j])%MOD;102 }103 }104memcpy (MAT1, MAT3,sizeof(MAT3)); the }106 voidMatrixquickmod (LL N)107 {108 Getmatrix ();109 for(inti =0; i < L; ++i) the {111Ret[i][i] =1; the for(intj =0; J < L; ++j)113TMP[I][J] =Mat[i][j]; the } the while(n) the {117 if(N &1) Matrixmul (ret, TMP);118 Matrixmul (TMP, TMP);119N >>=1; - }121 }122 };123 Trie ac;124 Charstr[ the]; the intMain ()126 {127 intm; - LL N;129 while(SCANF ("%d%lld", &m, &n)! =EOF) the {131 ac.init (); the for(inti =0; I < m; ++i)133 {134scanf"%s", str);135 Ac.insert (str);136 }137 ac.build ();138 ac.matrixquickmod (n);139 intAns =0; $ for(inti =0; I < AC. L ++i)141Ans = (ans + ac.ret[0][i])%MOD;142printf"%d\n", ans);143 }144 return 0;145}
POJ 2778 DNA Sequence (ac automata + Matrix fast Power)