[CSP-Sシミュレーション試験]:パリンドローム(ハッシュ+プレフィックスと二次元)

タイトル説明

  上記の二つの質問オフ$ YGH $秒のアイドル退屈した後、興味深い回文文字列の問題について考え始めます。
  彼は浮動文字列を持っていた前に。どうやら$ YGH $はmanacher $を$になるので、彼はすぐにこの文字列のパリンドロームサブの数を得ました。しかし、問題の数パリンドローム部分文字列は、彼が、彼はすぐに下付き文字列$ [L、R] $ストリングを決定するためのデータ構造を思い付くことに満足つもりされていない(同じパリンドロームリピートストリング)カウント。しかし、これはあまりにも単純な問題である、と彼は$ YYR $にスパイシーなチキン、スパイシーなチキンが、非常に$ YYR $全くないアイデアをテストする予定。
  だから、$ YGH $は、瞑想の$ YYRの$まだ袖を育てほこりの小片に、離れて高速化。


入力形式

文字列$ S $の最初の行。
整数の$ Tの$ 2行目は、問い合わせの数を表します。
二つの整数$ Lが$、$のR $の次に$ T $線、$クエリ文字列は添字S $ $ [L、R] $のサブストリングの回答を示しています。


出力フォーマット

$ Tの$の出力ラインは、それぞれがこの問い合わせに対する整数の答えを表します。


サンプル

サンプル入力:

Ababaab
2
L 3
3 7

出力例:

4
8


データ範囲とヒント

S | |、Tの\ leqslantデータの$ 20 \%の$について、$ことを確実にするために 500 $
データのための$ 40 \%$は$を確保| S |、T 5,000 $ \ leqslant
$ \ 100%の$のためのデータは、$を確保| S | \ leqslant 5000、T \のleqslant $ 100,000


問題の解決策

私はあなたにすべての幸せなナショナルデー、幸せなトレーニングをしたいです!

最初の質問は、より抽象的であるためには、二次元配列$マップ$の定義は、区間$場合は[L、R] $列はパリンドロームであり、その後、$マップ[L] [R] = 1 $、そうでなければ$ 0 $を。

そこで、我々が必要とするすべては、必要なポイント$(L、L)は、点$(R、R)$いくつかの$ 1 $を指示$です。

回文シーケンスを達成することができ、ハッシュの$ $プロセスの前に必要とされていない、の数は$ 1 $接頭辞を追求し、後で使用することができます。

時間の複雑さ:$ \シータ(N ^ 2 + T)$。

期待はスコア:$ $ 100ポイントを。

実際のスコア:$ $ 100ポイント。


コードの時間

#include <ビット/ STDC ++ H> 
名前空間STDを使用して、
int型のn; 
チャーCH [5001]。
INT [5001] S; 
int型マップ[5001] [5001]; 
符号なしの長い長いフラグ[5001]。
符号なしの長い長いHASH1 [5001]、HASH2 [5001]。
ボイドpre_work()
{ 
	フラグ[0] = 1。
	以下のために(INT i = 1; iが<= N; iは++)
	{ 
		フラグ[I] =フラグ[I-1] * 131。
		HASH1 [I] = HASH1 [I-1] * 131 + S [i]は、
	} 
	ため(INT I = N; I; I - )HASH2 [I] = HASH2 [I + 1] * 131 + S [i]は、
	以下のために(; iは= N <; I = 1 int型I ++)
		のための(INT J = I; J <= N; J ++)
			IF(HASH1 [J] -hash1 [I-1] *フラグ[J-I + 1] == HASH2 [I] -hash2 [J + 1] *フラグ[J-I + 1])
				マップ[I] [J] = 1。
	(; iが<= N I ++はiは1 = INT)のため
		のために(INT J = 1; J <= N; J ++)
			地図[I] [J] + =マップ[I-1]〜[J] +マップ[I] [J-1] -Map [I-1] [J-1]。
} 
int型のmain()
{ 
	scanf関数( "%sの"、CH + 1)。
	N = STRLEN(CH + 1)。
	(; iが<= N I ++はI = 1 INT)のために
		、 '+ 1 - S [i]がCHを[I] = 
	pre_work(); 
	INT T; scanf関数( "%のD"、&T)。
	(T--)一方
	{ 
		int型のL、R。
		scanf関数( "%dの%のD"、&L&R)。
		printf( "%d個の\ n"、マップ[R] [R] -Map [L-1] [R] -Map [R] [L-1] +マップ[L-1] [L-1])。
	} 
	0を返します。
}

RP ++

おすすめ

転載: www.cnblogs.com/wzc521/p/11616221.html
おすすめ