質問の意味: あなたは、これらのウイルスにn個のATGCからなる問ういくつかのウイルスの文字列の長さを与えることはどのように多くの文字列の数を含んでいません
分析:
我々は、第1の構造タイヤチャートを分析:トライ図プロトタイプAC自動機械側に状態を迅速に転送することができるように、標識された危険ノード(サフィックスノード不良ワード)を追加することであり、我々が構成したい長さnが悪い含みませんノード0に文字列右、それが離れて安全なノードから図トライN段階におけるプログラムの数ではない(図トライ状態遷移図です)
有向グラフでは、(明らかに古典的なマトリックス高速電力の問題である)スキームBの数kステップ徒歩は、隣接テーブルM [i] [j]の画像を構築する(原理は、独自の検索を必要とします)、 M [i] [j]はjに1をI =答えとして直接接続されたボーダーは、ANS = POW(M、K)、ANS [A] [B]を表し
書式#include <キュー> 書式#include <stdio.hに> する#include < 文字列の.h> 使用して 名前空間はstdを、 const int型 Max_Tot = 1E2 + 10 。 const int型の手紙= 4 ; const int型 MOD = 1E5; int型MAXN; INTの MP [ 128 ]。 構造体マット{ int型の M [ 111 ] [ 111 ]。}ユニット、M。 マット演算子 * (マットB、MAT) { マットRET。 長い 長いですバツ; 以下のために(int型 i = 0 ; I <MAXN; iは++ ){ ための(int型 J = 0 ; J <MAXN; J ++ ){ X = 0 。 用(int型のk = 0 ; MAXN <Kあり、k ++ ){ X + =(長い 長い)午前[I] [K] * BM [K] [J]。 } ret.mは[i] [j]は、X%= MOD。 } } 戻りRET。 } インラインボイド init_unit(){以下のために(int型 iは= 0 unit.mを[I] [I] =; I <MAXN iは++)1 。} マットpow_mat(マットint型N) { マットRET = 手段と 一方、(N){ 場合(N - 1)RET = RET * 。 A * = 。 N >> = 1 。 } 戻りRET。 } 構造体アホ{ 構造体StateTable { INT 次に[手紙]。 int型、フラグを失敗。 }ノード[Max_Tot]。 int型サイズ; キュー < 整数 > QUE。 インラインボイドのinit(){ ながら(!que.pop()que.empty())。 memsetの(ノード[ 0 ] .Next、0、はsizeof(ノード[ 0 ] .Next))。 ノード[ 0 ] = .failノード[ 0 ] .flag = 0 。 サイズ = 1 ; } インラインボイド挿入(チャー *のS){ int型今= 0 。 ために(int型 I = 0、S [i]は、iが++ ){ int型 IDX = 融点[S [i]は]。 もし(!ノード[今] .Next [IDX]){ memsetの(ノード【サイズ】.Next、0、はsizeof (ノード【サイズ】.Next))。 ノード【サイズ】.fail =ノード【サイズ】.flag = 0 。 ノードの[今] .Nextは[IDX] =サイズ++ ; } 今 = ノード[今] .Next [IDX]。 } ノード[今] .flag = 1 。 } //息子[i]が存在しない場合は1)、それは現在のノードのポインタの点を指しているフェイル // )私は(計算され保証さ後継ノード番号。 // 子が[i]が存在する場合2)は、現在のノードへのポインタを失敗さ失敗する // )私は(計算され保証さ後継ノード数へのポインタ。 インラインボイドBuildFail(){ ノード[ 0 ] .fail = 0 ; のための(int型 I = 0 ;私は手紙を<; Iは++ ){ IF(ノード[ 0 ] .NEXT [I]){ ノード[ノード[ 0 ] .NEXT [I] =不合格。0 ; que.push(ノード[ 0 ] .NEXT [I]); } そうノード[0 ] .Next [I] = 0 ; /// 必定指向根节点 } ながら(!que.empty()){ int型トップ= que.front()。que.pop(); もし(ノード[ノード[トップ] .fail] .flag)ノード[トップ] .flag = 1 。 以下のために(int型 i = 0 ; iは手紙を<; Iは++ ){ int型&V = ノード[トップ] .Next [I]。 もし(V){ que.push(V)。 ノード[V] .fail = ノード[ノード[トップ] .fail] .Next [I]。 } 他V = ノード[ノード[トップ] .fail] .Next [I]。 } } } インラインボイドBuildMatrix(){ ため(int型 i = 0 ; iは、サイズ<; I ++ ) のための(INT J = 0 ; J <サイズ、J ++ ) Mmを[I] [J] = 0 ; 以下のために(int型私= 0 ; iのサイズ<;私は++ ){ のために(int型 J = 0 ; jの<手紙; J ++ ){ 場合(ノード[i]が.flag &&!ノード[ノード[i]は.Next [J]] .flag) Mmの[i]と[ノードの[i]を.Next [J]] ++ ; } } MAXN = サイズ。 } } AC。 チャー S [ 11 ]。 INTメイン(ボイド) { MP [ ' A ' ] = 0 、 MP [ ' T ' ] = 1 、 MP [ ' G ' = 2 、 MP [ ' C ' ] = 3 ; INTのN、M。 一方、(〜のscanf(" %d個の%のD "、&M&N)){ ac.init()。 以下のために(int型 I = 0 ; iが<M; iが++ ){ scanf関数(" %sの" 、S)。 ac.insert(S)。 } ac.BuildFail()。 ac.BuildMatrix(); // ため(INT i = 0; iは<10; I ++){ // ため(INT J = 0であり、j <10; J ++){ // のprintf( "%dの"、Mmを[I] [J])。 // }プット( "")。 // }プット( "")。 init_unit(); M = pow_mat(M、N)。 // ため(INT i = 0; iは<10; I ++){ // ため(INT J = 0であり、j <10; J ++){ // のprintf( "%dの"、Mmを[I] [J])。 // }プット( "")。 // }プット( "")。 int型 ANS = 0 ; 以下のために(int型 i = 0 ; iは<ac.Size; iは++ ) ANS + = Mmを[ 0 ] [i]は、 ANS%= MOD。 printf(" %d個の\ n " 、ANS)。 } リターン 0 ; }