[リンク]タイトル
[タイトル]イタリア
紙を読んで誰かが、紙は多くの単語で構成されています。しかし、彼は何度も言葉を紙に表示され、今で各単語を紙に登場した回数を知りたいました。
[説明]
ACオートマトン問題3つのテンプレートに似ていますが、対象レコードをサブストリングは重なっていません。
カレンダー上背中、及び共通接尾辞に重畳対応する位置からインデックスを使用。理由:単語が登場した場合、対応する共通のサフィックスは確かに登場。
1の#include <cstdioを> 2の#include <アルゴリズム> 3 使用して 名前空間STDを、 4 のconst int型 N = 1005 。 5 のconst int型 M = 1E6 + 10 。 6 チャー S [N] [ 205 ]。 7 INTトライ[M] [ 26 ]、失敗[M]、エンド[M]、Szの[M]。 8 int型Q [M]、頭、尾; 9 int型ヘッド[M]、NXT [M]、[M]に、CNT。 10 int型 N、IDX = 1 。 11 12 無効 Add_edge(int型U、int型のV)。 13の ボイド DFS(int型U)を、 14 ボイド挿入(CHAR S []、INT Id)の{ 15 のint = P 1 。 16 のために(int型 I = 0、S [i]は、iが++ ){ 17 INTのt = sの[I] - [ A ' 。 18 であれば(!トライ[P] [T]) 19 トライ[P] [T] = ++ IDX。 20 、P = トライ[P] [T]。 21 Szを[P] ++ ; 22 } 23 エンド[ID]は= Pと、 24 } 25 ボイドビルド(){ 26 ヘッド= 1、尾= 0 。 27 のためには、(int型 = Iを0 ; iは< 26 ; iは++)トライ[ 0 ] [I] = 1 。 28 29 Q [++テール] = 1 。 30 一方(ヘッド<= テール){ 31 INT U = Q [ヘッド++ ]。 32 のために(int型 I = 0 ; iが< 26; iは++ ){ 33 INT =にトライ[U]を[I]。 34 もし{(TO) 35 = [TO]失敗トライ[I] [U]は[失敗]。 36 Q [++テール] = であり; 37 } 他{ 38 トライ[U] [I] = トライ[I] [U]は[失敗]。 39 } 40 } 41 } 42 } 43 空隙クエリ(){ 44 45 / * ための式(I = 1、P = 1 int型、iは<= N; iは++){ 46 、P = 1。 47 (INT J = 0; S [I] [J]; J ++)のために{ 48 INT T = S [I] [J] - 'A'; 49 、P =トライ[P] [T]。 50 Szを[P] ++; 51 } 52 } * / 53 54 のために(INT I = IDX; iは> = 1 ; i-- ){ 55 // Add_edgeは([i]は、I失敗); 56 Szの[失敗[Q [I]]] + = Szの[Q [i]は]。 57 } 58の // DFS(1)。 59 のためには、(int型 i = 1 ; iがn = <; iは++ ){ 60 のprintf(" %Dを\ n " 、Szの[終了[I])。 61 } 62 } 63 のint main()の 64 { 65 のscanf(" %d個"、&N) 66 のために(int型 i = 1 ; iが<= N; iが++ ){ 67 のscanf(" %sの" 、S [I])。 68 挿入(S [i]は、I)。 69 70 // のprintf( "###%の### \ n"は、S [I])。 71 } 72 ビルド()。 73 // printfの( "@@@@ \ nを"); 74 クエリ(); 75 リターン 0 ; 76 } 77の 空隙 DFS(INT U){ 78 のための(int型 I =ヘッド[U]; I; I = NXT [I]){ 79 、INT =への[I]。 80の DFS(TO)。 81 Szの[U] + = Szの[へ]。 82 } 83 } 84 空隙 Add_edge(INT U、INT V){ 85 NXT [++ CNT] = 頭部[U]。 86 頭[U] = CNT。 87 = [CNT]にV; 88 }