manacherについてA.
半径の文字列の長さを解決するためのmanacherパリンドロームサブアルゴリズム。
これは、直線的センターとしての地位に最長回文配列の半径のための文字列のそれぞれを解決することができます。
そして、この部分文字列の中心として各文字と、この回文文字列が回文文字列です。
アルゴリズムの時間計算量はO(N)です。
II。文字列の長さによって引き起こされる回文パリティサブ問題。
パリンドローム配列の長さが奇数である場合、それは中央のパリンドロームを持っている必要があり、中央部の両側のパリンドロームは、互いに対称です。
だから、とき回文文字列の長さは、それは、その後、どのようにそれを行うにはしません......でも、時間回文センターですか?
私たちは回文センターを建設人工考えます。
工事の方法は、文字列内の2つの文字のそれぞれの真ん中にあってはならないことと同じ元の文字列を挿入することがあるので、我々は見つけることができます:
元の文字列のパリンドロームのサブストリングの長さが奇数である場合、中心はパリンドローム元の文字列です。
元の文字列の長さの回文ストリングが偶数の場合は、回文新しく挿入された文字の中心です。
わかりました。この問題への完璧なソリューション。
三の.manacherアルゴリズムの流れ。
私たちはもう一度、最長の回文文字列の半径の中心としての地位に各文字の文字列を解決するためのmanacherアルゴリズムを確認します。
我々最長パリンドローム配列の半径の中心をP []という配列を入力としてそれ自体に各文字列。
O(n)との時間の複雑さは、我々は、再帰的な方法によりp列を解決する必要があり、この問題を完了します。
1.パリンドローム対称文字列
私たちは回文文字列の対称上記。
S [11]:今、私たちは、文字列があるとしabababababa
私たちは、[5](インデックス0から始まる)は、文字列回文が回文中央sと、彼はパリンドローム配列の文字列であることをはっきりと見ることができます。
観測S [2]パリンドローム配列の中心として、およびSではない[8]パリンドローム配列の長さに等しいが中心に正確に等しいですか?
2. 2つの重要なパラメータ:MAXR、ミッド。
だから我々は、pのp [2]を押し、[8]ことができますが、これらは前提条件、すなわち、P [5]≥4です。
中央前提パリンドロームは、2つのサブストリングパリンドローム対称中心点へパリンドローム大きい文字列であるので、それらは同じでなければならない最長の回文配列の半径を拡大することができます。
だから我々は、転送を保証するために、右のポイントと中央ミッドMAXR大型回文文字列を維持する必要があります。
しかし、P []は、最長の回文半径であるように、このシフトは、必ずしもではないので、我々は行に暴力を拡大しました。
全体的な複雑性O(n)です。
III。コード
外側の拡大の過程で、文字列の左側と右側が異なるシンボルかもしれないそうTLEに授与されることに注意してください。
羅区[テンプレート] manacherアルゴリズム:
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 長い 長い N、ANSはp [ 22000002 ]。 チャー C [ 11000001 ]、S [ 22000002 ]。 INT メイン() { scanf関数(" %sの"、C + 1 )。 N = STRLEN(C + 1 )。 以下のために(int型 i = 1 ; iは= N <; iは++ ) { S [iが * 2 =のC]を[i]は、S [iが* 2 - 1 =] ' !" ; } S [ 0 ] = ' + ' 。 S [ 2 * N + 1 ] = " !" ; S [ 2 * N + 2 ] = ' - ' 。 長い 長い MAXR = 0、ミッド= 0 ; 以下のために(int型 i = 1 ; iが<= N * 2 ; iは++ ) { 場合、P [i]は=分(私はMAXRを<)(MAXR-I、P [ミッド* 2 - I])。 他のp [i]は= 0; ながら - (S [IP [i]が1 ] == S [iが[I] + Pを+ 1、P [I] ++])。 場合(iは[I]> Pを+ MAXR) { MAXR = iが+ Pを[I]。 ミッド = I; } } のための(int型 i = 1 ; iが<= N * 2 ; iが++ ) { ANS = MAX(ANS、P [I])。 } のprintf(" %のLLD " 、ANS)。 }