最長の回文配列(Manacherアルゴリズム)

http://acm.hdu.edu.cn/showproblem.php?pid=3068

最長の回文

問題の説明
文字列Sは小文字のみ英語の文字で与えられ、B、C ...のy、 zの最長の長さSパリンドロームの文字列を求めているからなる。
回文はリバースリードの文字列と同じですABA、アバなど
 

 

入力
入力された場合、小文字の文字入力ラインaのない120の以上のグループ、ストリングS Bの複数のセットC ... Y、Z成分
空行ケース(不空行によって分離された2つの群の間処理)
文字列の長さLEN <= 110000
 

 

出力
整数xの各行は、ケースのセットに対応する、文字列の長さは、ケースに含まれる最も長いパリンドローム基を表します。
 

 

サンプル入力
AAAAのABAB
 

 

サンプル出力
4 3
 

 

ソース
 

 

推薦します
LCY | 我々は慎重にあなたのためのいくつかの同様の問題を選択している:   1358   1686   3336   3065   3746
#include <cstdioを> 
する#include <CStringの> 
する#include <cmath> 
の#include <アルゴリズム> 
の#include <iostreamの> 
する#include <アルゴリズム> 
の#include <iostreamの> 
する#include <cstdioを> 
する#include < ストリング > 
の#include <CStringの> 
書式#include <stdio.hに> 
する#include < 文字列の.h>
 使用して 名前空間はstdを、
const  int型 N = 500009 ;
int型のC [N]。
int型のn;
];
 チャー A [ 110009 ];
 CHAR B [ 220 009 ]; 


int型のmain()
{ 

    ながら(〜scanfの(" %S " 、A))
    { 
        int型レナ= STRLEN(A);
         // により処理ストリング外来文字が増加し、変更の数が偶数回文配列 
        B [ 0 ] = ' $ ' ; 
        Bは[ 1。 =] ' ' ;
         int型 = L 2 ;
         のためint型 I = 0 ;私はレナを<; I ++
        { 
            B [L ++] = A [I]、
            B [L ++] = ' ' ; 
        } 
        B [L] = ' \ 0 ' ;
         INT MX = - 1 ;    // 右端の右境界パリンドローム:それはパリンドローム位置を参照して、文字列のサブ・ロケーション前の右端の場所に達する
        のint LEN = -を1。;
         INTミッド; // 中間中心最長の回文配列に
        するためのINT I = 0。 Iは、Lを<; Iは++ 
        { 
            // 共通の4例を
            
            IF(IはMXを<)//文字列は最長パリンドローム左の位置の前にある場合は
            {
                 // 次の式は、3例が含まれています
                 @ 。I 1対称点である- 2 MIDは、*
                 // 横断対称点として
                 //がポイントに基づくことができます私は、最長文字列パリンドロームの長さを決定する
                 // 2例は、パリンドロームを誘導することができる式Iの最長ランレングス時間計算は対称点から直接(1)Oであるが;
                 // R必要があります問い合わせを継続するために2つの側面に基づきます。
                P [I] =分(P [ 2 * MID - I]、MX - I); 
            } 
            
            そう// それが正しい境界にトラバースの場合
            、{ 
                P [I] = 1 ; // P文字配列がパリンドローム記録されています最長半径パリンドロームストリング列の各文字の長さ
            }
             しばらく- (B [I P [I]] == B [IはP [I]が+])//のクエリの両側には 
                P [I] ++ ;
             IF(MX <P [I] + I)
            { 
                MID = I。
                MX = P [I] + I; 
            } 
            でlen = MAX(LEN、P [I] - 1。); // 最長文字列回文文字列全体を記録
        } 
        COUT << lenの<< ENDL; 
    } 


    戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/nonames/p/11282901.html