NOI2014・動物園

タイトル説明

最近、プリンシパルは動物園の動物、より多くの怠惰ない。例えば、ペンギンだけ孟は観光客を食べて販売します。修復不健康な習慣の動物園に、動物は動物は学習アルゴリズムだから、食べるために観光客に自分の本当の能力、オープンアルゴリズムクラスへの主要な決定的があります。

ある日、主要な動物はKMPアルゴリズムを説明します。

校長:「次の配列を意味プレビュー誰行う隣の弦Sの場合、その長さLは、我々は時間O(L)で指定された配列を検索することができます。?」

パンダ:「私は、コンフィギュレーション文字列sの前の文字のサブ文字列の両方のサフィックスと接頭辞が(自身を除く)、最大長次に[I]と呼ばれる文字列」

監督:「あなたができることは非常に良い例!?」

パンダ:Sのabcabの最初の5つの文字は、AB両方のサフィックスがそれの前に置かれ、長い文字列を満たすには、このプロパティを見つけるされているため、「例Sは、次の[5] = 2 abcababcです。同様に、星も次[1] =次の[2] =次の[3] = 0、次の[4] =次の[6] = 1、次の[7] = 2、次の[8] = 3 。 "

主な賞賛パンダ深刻予備校の学生。彼はその後、時間のO(L)にどのように決定された次の配列の詳細な報告をしてくれました。

クラスの前に、校長は疑問提起:「KMPアルゴリズムが唯一の文字列が、私は、文字列で構成されるSの前にサブのnum文字の11のより強力な配列を得るために、私は今、希望の次の配列を見つけることができますが、それは両方が接尾辞です。また、接頭辞と接尾辞は、接頭辞と重ならない、そのような文字列の数[i]がNUMとして示す。SはAAAAA例えば、NUM [4] = 2であり、これは前者4 SためAA満足の性質は「接尾辞や接頭語の両方で」AAAAのための文字、接尾辞と接頭辞が重複しないようにしながら。AAA満足の性質が、残念ながらこのサフィックス「接尾辞や接頭語の両方である」が、プレフィックスは、重畳されたカウントすることはできない。同様に、NUM [1] = 0、NUM [2] = NUM​​ [3] = 1、NUM [5] = 2 "

最後に、主な受賞条件、チョコレートのペアの箱を行うには、学生への一等賞を与えます。これらの言葉を聞いた後、睡眠レッスンペンギンはすぐに目を覚まします!しかし、問題を解決するペンギンとしない、そして助けのためのあなたに動物園を訪問します。あなたはペンギンの検索num個の配列、それを支援するプログラムを書くことができますか?

特に、多数の出力を避けるために、あなたは出力NUMする必要はありません[i]は、それぞれ数ある、あなただけ(NUM + +1しました[1])を出力する必要がある(NUM [2] + +1) ... *(NUM [L] 1)モジュロ十億七の結果です。

エントリー

線1のみを含む一つの正の整数n、テストデータのセットの数。

その後、n行、各行は、テストデータのセットを記述する。各試験は、Sは、被写体の詳細な説明定義のみストリングSを含有します。データSは小文字のみが含まれていることを確認します。余分な空白行が含まれないファイルを入力し、最後の行に余分なスペースはありません。

輸出

n行を含む、試験データ回答のセットを記述する各行は、答えは、入力データの順序と一致する順序でなければなりません。各試験のために、唯一それを出力するテストデータのセットに対する回答の結果は十億七を法示す整数を、必要とします。出力ファイルには、余分な空白行を含めることはできません。

サンプル入力1

3によって
AAAAA
アブ
Abcababc

サンプル出力1

36
1
32

プロンプト

[データ範囲]

n≤5、L≤1,000,000

問題の解決策

文字列の次の木、その次に接続されたエッジ、すなわち各ポイントで構築することができます。
何の制約を「重複しない」がない場合は、[I] NUMを尋ねるツリー次のポイントの深さは私です。
条件のみ中間位置を維持する必要があった、現在の設定点DFS iが、根、<の最大= I / 2のパスのI中間
必要NUM [I]は、DFSに中間に相当する時間である私奥行き
移動距離から全体の動きを通してMIDがより小さいI O(N)

コード

···C ++

<ビット/ STDC ++。H>含みます

名前空間stdを使用。

N 1000000を定義します

長い長いLL定義

モッズ1000000007を定義します

RGレジスタを定義します

インラインint型リード(){
int型、S = 0、WW = 1。
チャーCH = GETCHAR()。
一方、(CH < '0' || CH> '9'){IF(CH == ' - ')WW = -1; CH = GETCHAR();}
ながら( '0' <= CH && CH <= ' 9' ){S = 10 * S + CH - '0'; CH = GETCHAR();}
戻りS * WW。
}

int型nは、CNT;
チャーS [N + 5]。
INTヘッド[N + 5]、NX [N + 5]。

構造体ノード{
次のint、デ。
} E [N + 5]。

インラインボイドaddedge(int型A、INT b)は{
CNT ++。
E [CNT] .des = B。
E [CNT] .next =ヘッド[A]。
ヘッド[A] = CNT。
}

インラインボイドプレプロ(){
NX [1] = 0;
int型のp = 0;
{(I ++; I <= N RG INT I = 2)のための
(!P && S [p + 1] = S [i])とP = NX [P]一方、
(S [p + 1] == S [i])とP ++場合。
NX [I] = P。
}
}

INT S [N + 5]、DEP [N + 5]、NUM [N + 5]。
int型のトップ、ミドル、

インラインボイドDFS(INT U){
S [++トップ] = U。
IF(U)、一方((S [ミッド+ 1] << 1)<= U)中間++。
NUM [U] = DEP [S [中間]。
以下のために(RGはINT iがヘッド= [U]; I; iは、E [I] .next =){
int型、V = Eを[I] .des。
DEP [V] = DEP [U] + 1。
int型温度=ミッド;
DFS(V);
半ば=一時;
}
top--。
}

INTのmain(){
int型T =読み取ります()。
(T - )、一方{
memsetの(頭、0、はsizeof(ヘッド))。
CNT = 0;
scanf関数( "%s"は、S + 1)。
N = STRLEN(S + 1)。
プレプロ();
以下のために(RG INT iが= 1; I <= N; I ++)addedge(NX [i]は、I)。
トップ=半ば= 0;
DFS(0)。
LL ANS = 1。
以下のために(RG INT iが= 1; I <= N; I ++)ANS = ANS *(LL)(NUM [I] + 1)%のMOD。
coutの<< ANS <<てendl;
}
0を返します。
}
`` `

おすすめ

転載: www.cnblogs.com/xh092113/p/12239694.html