[羅区P3966] [TJOI2013]ワード

タイトル効果:あり$ $ 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を返します。
}

  

おすすめ

転載: www.cnblogs.com/Memory-of-winter/p/11304687.html