タイトル説明
Pangtouは魚のように荒れた海で釣りをしています。
彼は多くの場合、毎日、彼はキャッチ魚に時間の連続期間を選ぶだろう、魚の多くの異なる種が川であり、キャッチ魚を川に行き、各時点ではそこだけで魚が見えるだろう、と魚Pangtouに触れることができるようになります(彼は荒れた海の言葉で釣りをしている場合)。
魚は、彼が盲目であるため、魚に触れた後、彼は、キャッチ魚行の魚年代触知できる、統計的リターンの今日に触れるだろう、彼は同じ種である魚伝えることができ、かつ最後に知ることができません魚の種類、ので、彼は正の整数の種類に応じて魚を入れ、同じ魚の同じ番号を使用し、異なるラベルを持つ別の魚で、スマートPangtouは辞書順最小のラベル方法を選択します。
異なる時間に見つけPangtouキャッチ魚は同じ利点を有していてもよく、二つの異なる利益場合にのみ、タッチの異なる数または私は最初のタッチが魚の異なる数を$という私な$ $ $魚の存在。
Pangtouは、荒れた海での釣りの終了のいずれかの時点で、いつでもオフにへまをし始めることができますが、少なくとも一つの魚に触れます。彼はあなたが彼に異なる可能なトータル・リターンの数をカウントしたいです。(彼は唯一の荒れた海での時間の釣りの継続期間を選択する必要があります)。
データ範囲
$ 1 \ a_iを\ K \ 5 \タイムズ10 ^ 4 $
問題の解決策
我々は最小アウトで各サフィックスを検討することができ、その後、ソート答えは$ \ FRAC {N \倍(N + 1)}、{2}である場合 - \和LCP(str_i、str_ {I + 1})$ 。
$ $ \総和(next_i-i)は、\回のp ^ I $、どこ同じ$ next_i $へと$ Iは、次の位置番号を$として表現ハッシュ$を考えてみましょう、いない場合、それは$ I $に設定され、その同じである2つの極小で表されるハッシュ$ $クロストークと同様に反射させることができます。
半分$ハッシュ$とき、ソート後、木の社長とメンテナンスの値の$ハッシュ$サブストリングを考えると、(2カザフ分析)をすることができます。
効率性:$(nlog ^ 3N)O $
コード
#include <ビット/ STDC ++ H> の#define LLは、長い長い の#define U符号なし長い長い 使用して 名前空間STDを、 CONST INT N = 5E4 + 5、M = 2E6 + 5 。 constの UB = 793999 ; 整数nは、[N]、LS [M]、RS [M]、T [N]、T、P [N]、NX [N]。 LLはANS; U S [M]、B [N]。セット < INT > S [N]。 #define半ば((L + R)>> 1) ボイド UPD(INT&X、INT Y、INT L、INT R、INT V、U W){ X= ++ T; S [X] = S [Y] + W。 LS [X] = LS [Y]、RS [X] = RS [Y]。 もし(L == R)のリターン; もし(MID> = V)UPD(LS [X]、LS [Y]、L、中、V、W)。 他 UPD(RS [X]、RS [Y]、ミッド+ 1 、R、V、W)。 } U QRY(int型のx、int型 L、INT R、INT L、int型R){ 場合(L <= L && R <= R)リターンS [X]。 もし(MID> = R)リターン(LS [X] QRY(LS [x]は、L、中、L、R):0 )。 もし(ミッド<L)のリターン(RS [X] QRY(RS [x]は、中間+?1、R、L、R):0 ); リターン(LS [X] QRY(LS [x]は、L、中、L、R):0)+(RS [X] QRY(RS [x]は、中間+?1、R、L、R):0 ); } U HS(INT L、INT R){ リターン(T [L] QRY(T [L]、?1、N、L、R):0 );} int型 LCP(int型のx、int型Y){ int型 L = 0、R = N-MAX(X、Y)+ 1 ; 一方、(L < R){ INT iは=(L + R + 1)>> 1; もし(HS(X、X + I- 1)* B [X] == HS(Y、Y + I- 1)* B [Y])、L = I。 他に、R = I- 1 。 } 戻りL。 } INT順位(int型のx、int型I){ リターン(* S [I] LOWER_BOUND(X)) - X。 } BOOL CMP(int型のx、int型のY){ int型 L = LCP(X、Y) もし(X + L> N)、リターン 1。もし(Y + 1> N)戻り 0 ; リターンPOS(X、X + L)<POS(Y、Y +のL); } int型のmain(){ CIN >> nであり; B [ 0 ] = 1 ; 以下のために(INT iが= 1 ; <I = N; I ++ ) のscanf(" %dの"、&[i])と、B [I] = B [I- 1 ] * B、 P [I] = I、S [ [I](i)を挿入します。 用(INT I = N; I; i-- ){ T [I] = T [I + 1 ]。 もし(NX [I])UPD(T [I]、T [i]は、1 、N、 NX [I]、B [N -i + 1] *(NX [[I]] - I))。 NX [I] = I。 } stable_sort(P + 1、P + N + 1、CMP); ANS = 1LL * N *(N + 1)/ 2 。 以下のために(INT iが= 1 ; I <N; I ++)ans- = LCP(P [I]、P [I + 1 ])。 printf(" %のLLD \ n "、ANS)。リターン 0 ; }