ビス最長の回文配列

問題の意味

最も長い文字列回文ダブル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 }

 

おすすめ

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