タイトル効果:あり$ $ N-文字列、各文字列はシーク時間、すべての文字列で発生
問題の解決策: $ AC $オートマトン、各ノードは$ SZ $の後にあるプラスワン、それぞれ$ $を失敗木々と$ SZの$サブツリーのための出現の文字列
ポイントカード: $ AC $オートマトンのルートノードは、時間がないの$ 1 $、$ビルド$すべての空の$ NXTは、[1] [i]が$ 1 $を割り当て
C ++コード:
#include <cstdioを> する#include <アルゴリズム> の#include <iostreamの> する#include <キュー> のconst int型MAXN = 1E6 + 10。 std ::文字列s。 N INT、RET [210]。 名前空間AC { INT NXT [MAXN] [26]、[MAXN] [MAXN]、IDX = 1、CNTを失敗します。 INTインサート(スタンダード::文字列s){ int型のP = 1。 (チャーCH:S)のための{ IF(NXT [P] [CH - 'A'])P = NXT [P] [CH - '']。 他のp = NXT [P] [CH - 'A'] = ++ IDX。 ++ CNT [P]。 } Pを返します。 } ボイドビルド(){ 静的はstd ::キュー<整数> Q。 以下のために(INT i = 0; iは<26; ++ I) (NXT [1] [i])と失敗した場合[NXT [1]〜[I] = 1、q.push(NXT [1] [i])と; 他のNXT [1] [I] = 1; (!q.empty()){ながら、 int型のu = q.front(); q.pop(); ための式(I 0 = int型、iが26 <; ++ i)が (NXT [U]は[i])と失敗した場合[NXT [U] [I] = NXT [I]、q.push [U]は[失敗します] (NXT [U] [I])。 他のNXT [U] [i]は= NXT [失敗[U]]は[I]; } } int型のヘッド[MAXN]、CNT。 構造体のエッジ{ 、NXTにINT。 } E [MAXN]。 ボイドaddedge(INT A、INT B){ E [++ CNT] =(エッジ){B、ヘッド[A]}。[A] = CNTヘッド。 } ボイドDFS(UをINT){ {(; I I = E [i]は.nxt int型I =ヘッド[U]、V)のために 、V = E [I] .TO。 DFS(V); CNT [U] + = CNT [V]。 } } ボイド(解く){ (I = 2をint型、I <= IDX; ++ i)のためのaddedge([i]は、I失敗); DFS(1)。 } } int型のmain(){ std ::イオス:: sync_with_stdio(偽)、STD :: cin.tie(0)、STD :: cout.tie(0); std :: cinを>> N; {(; iがN <++ iが0 = INT)のため のstd :: CIN >> S。 RET [i]は= ACは::(複数可)を挿入します。 } AC ::ビルド()、AC ::解きます(); (I = 0 int型、iがN <; ++ i)についてはstd :: COUT << AC :: CNT [RET [i]が] << 'の\ n'; 0を返します。 }