長期滞在ピット
複数の文字列マッチング問題オートマトン1.AC
テキスト内の各パターン文字列の出現回数をカウントするには、現在の各ノードに対して直接$は$暴力を失敗ジャンプすることはできません
コンプレックスは$ O(N ^ 2)$に分解することができます
$ AAAAAA ...... AAA $がオフにスナップすることができます
アウト建て$ポインタを失敗$を逆にするには、それは、木をクリアし、その統計サブツリーのサイズです
1の#include <ビット/ STDC ++ H> 2 使用して 名前空間STDを、 3 CONST INT N = 2 * 1E5 + 100 。 4 INT N、TOT、WH [N]、CNT [N]。 5 構造体ノード 6 { 7 INTの息子[ 26 ]、失敗。 8 } SH [N]。 9 ストリングS、T。 10ベクター< INT > E [N]。 11 ボイドビルド(INT X) 12 { 13 のint p = 1 。 14 のために(INT iは= 0 ; iが<(INT)t.size(); I ++ ) 15 { 16 であれば(SH [P] .son [T [I] - !' ' ]) 17 { 18 TOT ++ 。 19 SH [P] .son [T [I] - ' ' ] = TOT。 20 } 21 P = SH [P] .son [T [I] - ' ' ]。 22 } 23 WH [X] = P。 24 } 25 ボイド build_fail() 26 { 27 キュー< INT > Q。 28 q.push(1 )。 29 ながら(!q.empty()) 30 { 31 INT X = q.front()。 32 q.pop()。 33 のために(INT iが= 0 ; I < 26 ; I ++ ) 34 { 35 であれば(!SH [x]は.son [I]) 36 { 37 であれば(x == 1 ) 38 SH [X] .son [I] = 1 。 39 他の 40 のSH [X] .son [I] = SH [SH [X] .fail] .son [I]。 41 } 42 他の 43 { 44 であれば(x == 1 ) 45 SH [SH [X] .son [I]失敗= 1 。 46 他の 47 のSH [SH [X] .son [I] =失敗。SH [SHを[X] .fail] .son [I]。 48 q.push(SH [X] .son [I])。 49 } 50 } 51 } 52 } 53 ボイド一致() 54 { 55 INT P = 1 。 56 のために(INT iは= 0 ; iが<(INT)s.size(); I ++ ) 57 { 58 、P = SH [P] .son [S [I] - ' ' ]。 59 CNT [P] ++ ; 60 } 61 } 62の空隙 DFS(int型のx、int型FA) 63 { 64 のために(INT iは= 0 ; I <(INT )E [X] .size(); I ++ ) 65 { 66 INT U = E [X] [I]; 67 であれば(U =!FA) 68 { 69 DFS(U、X)。 70 CNT [X] + = CNT [U]。 71 } 72 } 73 } 74 のint main()の 75 { 76 TOT = 1 。 77 のscanf(" %d個"、&N) 78 のために(INT iは= 1、I <= N; I ++) 79 { 80 CIN >> T。 81 ビルド(I); 82 } 83 build_fail()。 84 cinを>> S。 85 試合(); 86 のために(INT iは= 2、iは<= TOT; I ++ ) 87 { 88 E [I] .push_back(SH [i]の.fail)。 89 E [SH [i]は.fail] .push_back(I)。 90 } 91 DFS(1、1 )。 92 のための(int型 I = 1; I <= N; I ++ ) 93 のprintf(" %D \ n " 、CNT [WH [I])。 94 }