コンセプト
クエリ文字列のハッシュ値
我々は、それはいくつかの非常に便利な性質を持っているので、通常は例えば、それは接頭辞と同様の性質を持っている、バイナリのハッシュをハッシュさについて話しています。
時間ベース+ S [i]の時間$ \ [I] = [I-1] [i]は進$ベース$の$を、その後明らかに$ H列は、ハッシュ値のプレフィックス$ Hと呼ばれると仮定する。
ノートの$ P [i]は$は、その後、我々はO(1)$文字列のハッシュ値を取得することができる$、$ $ I $ $ベースパワーです。
typedefの符号なしの長い 長いULL。 ULL get_hash(int型 L、INT R){ 戻り H [R] - H [1 - 1 ] * P [R - L + 1 ]。 }
前記は、$ P [R-L + 1] $左の$ R-L + 1 $ビットに対応乗じ。
同様に、我々はO(1)$の文字を削除するには、文字列のハッシュ値を取得$することができます。
ULLのget_s(int型 L、int型の R、int型X){ 戻り get_hash(L、X - 1)* P [R - X] + get_hash(X + 1 、R)。 }
例
質問の意味:文字列$ Sの$を考えるには、$ S $文字列は、文字列$ U $を与えるために$ T $の文字を挿入し、文字列$ T $を取得するには、最初の時間をコピーします。現在の$ S $を再構築するために必要な文字列の$ U $を、与えられています。
分析:
列挙各位置は、残りの二つは、ハッシュ値に決定されたものによれば、同じ文字列でなければなりません。
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 typedefの長い 長いLL。 typedefの符号なしの長い 長いULL。 CONST ULLの基地 = 233 。 const int型 MAXN = 2000000 + 10 。 ULL H [MAXN]、P [MAXN]。 チャーS [MAXN]。 int型のlen; 無効のinit() { LL ANS = 0 。 以下のために(int型私= 0 ;私がlen <;私は++ ) { ANS=(ANS * 基底)+ (ULL)S [i]は、 H [I] =のANS。 } P [ 0 ] = 1 。 以下のために(int型 i = 1 ; iは= LEN <; iは++ ) { P [I] = P [I- 1 ] * 基地; } } インラインLL GETHASH(INT L、INT R) { 戻り H [R] - H [1- 1 ] * Pの[R-L + 1 ]。 } インラインLLデル(int型 L、INT R、INT X) { IF(X <L || X> R&LT) を返すGETHASH(L、R&LT); 戻り、X-をGETHASH(Lを1)* P [RX] + GETHASH(Xの+ 1 、R&LT); } インラインint型のチェック(INT X)// 正当性チェックXビット除去 { IF = LEN /(X < 2デル(&& 0、lenの1、X)==デル(0、LEN >> 1、X)* P [LEN >> 1 ] +デル(0、LEN >> 1 、X)) リターン 1。; 他 IF(X> LEN / 2&&デル(0、len- 1、X)==デル(0、(LEN >> 1) - 1、X)* P [LEN >> 1 ] +デル(0、(LEN >> 1) - 1 、X )) リターン 1 。 それ以外 の戻り 0 ; } int型のmain() { scanf関数(" %のD "、およびLEN)。 scanf関数(" %sの" 、S); その中に(); int型 CNT = 0 ; int型 II = - 1 ; ; LL NUM ため(int型 I = 0 ; IはLEN <Iは++ ) { IF ((I)を確認) { CNT ++ ; IF( - II == 1 ) { II = I; NUM =デル(0、LEN - 1 、I); } 他 { IF(DEL(0、LEN 1、II)デル==(0、LEN 1。 、私は)) // 同じ文字列であってもよいです cnt-- ; } } もし(CNT == 2 ) { のprintf(" NOT UNIQUEの\ n " ); リターン 0 ; } } もし(CNT == 1 ) { int型、M = 0 。 用(INT J = 0 ; J <LEN; J ++) // 输出结果 { 場合(jは== II)を 続け、 printf("%のC "S [J]); M ++ ; もし(m個の==(len- 1)/ 2 ) ブレーク; } のprintf(" の\ n " ); } もし(CNT == 0 ) { のprintf(" 不可能\ nを" ); } の戻り 0 ; }
参考リンク:https://loj.ac/submission/576434