タイトル説明
上記の二つの質問オフ$ 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 ++