#質問の意味
最長の回文の部分文字列を見つけ、文字列を与えられました、
#説明
パリンドローム配列がパリンドロームの半径の長さで表すことができる決定されない
列挙すべての点は、現在の点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 }