[AC]ワードオートマトン

[リンク]タイトル

https://loj.ac/problem/10060

 

[タイトル]イタリア

紙を読んで誰かが、紙は多くの単語で構成されています。しかし、彼は何度も言葉を紙に表示され、今で各単語を紙に登場した回数を知りたいました。

 

[説明]

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 }
非重複の数を数えます

 

おすすめ

転載: www.cnblogs.com/Osea/p/11366999.html