回文最長の部分文字列(ハッシュ一致したサブストリング

質問の意味
最長の回文の部分文字列を見つけ、文字列を与えられました、

説明
パリンドローム配列がパリンドロームの半径の長さで表すことができる決定されない
列挙すべての点は、現在の点iがあると仮定
チェックすべての偶数長と奇数長
、I-1〜Iは、lenの{に奇数の場合は}と{I 1、I + LEN}
サブ回文文字列の長さは、2 * LEN + 1され
、I-1 {I-lenのへと{I、iがlenの-1 +ここで、偶数

各点、半回文半径の長さを介して
二つの点
の最小の長さは0でなければならない
最大の長さは、現在のポイントの前のポイントに、これらの2つの長さの終わりに、現在の点後の点を開始すべきときに奇数の長さを最小
も長さが現在のポイントの前のポイントである、現在、最後の最小

 

1の#include <ビット/ STDC ++ H>
 2  の#define ULLのunsigned long長い
 3  使用して 名前空間STDを、
4  CONST  INT N = 1E6 + 10、P = 131 5  チャーS [N]。
6  INT M。
7  INT トン。
8  ULL H1 [N]、H2 [N]、P [N]。
9 ULL geth1(INT L、INT R){
 10     リターン H1 [R] - (H1 1- [ 1 ] * P [R-L + 1 ])。
11  }
 12 ULL geth2(INTL、int型R){
 13     リターン H2 [L] -H2 [R + 1 ] * P [R-L + 1 ]。
14  }
 15  int型のmain(){
 16     P [ 0 ] = 1 ;
17     のためにINT iは= 1 ; I <= Nであり; I ++)P [I] = pは[I- 1 ] * P。
18  
19     ながら(scanf関数(" %S "、S + 1)&&のstrcmp(S + 1" END " {))
 20        COUT << " ケース" << ++ T << " " ;
 21         INT ANS = 0、LEN = STRLEN(S + 1 );
 22         H2は[lenの+ 1 ] = 0 ;
 23         INTは iは= 1 ; I <= LEN; I ++) H1 [I] = H 1 [I- 1 ] * P +(S [I] - ' ' + 1 );
 24 INT I = LEN; I; i--)H2 [I] = H 2 [I + 1 ] * P +(S [I] - ' ' + 1 );
 25 26 のために         
        INT I = 1 ; I <= LEN; I ++ ){
 27           のint L = 0は、R =分(I- 1は、lenの-I)であり; // 最大長は左右に長さ、すなわち、2分で
28           一方、(L < R&LT){
 29              INT MID = L + R&LT + 1。 >> 1。;
 30              IF(geth1(I-MID、I- 1)== geth2(I + 1、I + MID))
 31である                 L = MID;
 32              
33は                 R&LT半ば= 1 ;
 34である          }
 35           ANS = MAX(ANS、L * 2+ 1 );
 36  
37 [           L = 0は、R =分(I- 1、I-LEN + 1); // それの右半分に現在のカウント+1し
38である 
39           ながら(L < R&LT){
 40              INT MID = Lの+ + R&LT 1。 >> 1。;
 41れる             IF(geth1(MID-I、I- 1。)== geth2(I、I +半ば1。 ))
 42である                 L = MID、
 43は             
44である                 R&LT半ば= 1。;
 45           }
 46は、           ANS最大=(ANS、L * 2);
47         }
 48         COUT << ANS << ENDL。
49     }
 50  
51 }

 

おすすめ

転載: www.cnblogs.com/hhyx/p/12514876.html