最も長い文字列回文ダブルTを求めてS、文字列sを与えられ、T、X、Y及びX二つの部分に分けることができ、Yはパリンドローム配列であります
#説明
iは、拡張文字列と右エンドポイントパリンドロームの軸を表し、左に[i]の基底manacher及びR ON [i]の点をL LがRのアレイを求めます
1の#include <iostreamの> 2の#include <cstdioを> 3の#include <CStringの> 4 5 使用 名前空間STDを、 6 7 CONST INT MAXN = 200010 。 8 のchar [MAXN]、S [MAXN << 1 ]。 9 のint L [MAXN << 1 ]、R [MAXN << 1 ]。 10 INT N、HW [MAXN]は、ANS。 11インラインボイドmanacher(){ 12 INT maxright = 0 、ミッド。 13 のための(int型I = 1 ; I <N; ++ I){ 14 であれば(私は< maxright) 15 HW [I] =分(HW [(MID << 1)-1]、HW [中間] +ミッドI)。 16 他 17 HW [I] = 1 。 18 一方、(S [I + HW [I]] == S [I- HW [I]) 19 ++ HW [I]。 20 であれば(HW [I] + I> maxright){ 21 maxright = HW [I] + I。 22 半ば= I; 23 } 24 } 25 } 26 27 空隙変化(){ 28の S [ 0 ] = S [ 1 ] = ' #' 。 29 のために(INTは iは= 0、I <N; ++ i)が{ 30 S [I * 2 + 2 ] = [I]を、 31 S [iが* 2 + 3 ] = ' #' 。 32 } 33 N = N * 2 + 2 。 34の S [N] = 0 ; 35 } 36 37インラインINT MAXX(INT A、int型B){ 38 リターン A> B?:B; 39 } 40 41 INT メイン(){ 42 のscanf(" %S " ); 43 N = STRLEN(A)。 44 変化()。 45 manacher()。 46 INTは今= 0を。 47 のために(INT iが= 0 ; iが<N; ++ i)が 48 ながら(今<= I + HW [I] - 1 ) 49 L [今++] = I。 50 今= N。 51 のために(INT I = N- 1、I> = 0 ; - I){ 52 ながら(今> = I-HW [I] + 1 ) 53 R [今- ] = I。 54 } 55 INT ANS = 0 。 56 のために(INT iは= 0 ; iは<N; ++ I) 57 ANS = MAXX(ANS、R [I] - L [I])。 58 のprintf(" %dの" 、ANS)。 59 }