LightOJ1258(线性回文串

题目:给出一个序列,求最少在后面加多少字符形成一个回文串。

思路:裸的manacher,注意枚举的起点和终点。

/*
* @author:  Cwind
*/
///#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <map>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <set>
#include <cmath>
using namespace std;
#define IOS std::ios::sync_with_stdio (false);std::cin.tie(0)
#define pb push_back
#define PB pop_back
#define bk back()
#define fs first
#define se second
#define sq(x) (x)*(x)
#define eps (3e-7)
#define IINF (1<<29)
#define LINF (1ll<<59)
#define INF (1000000000)
#define FINF (1e3)
#define clr(x) memset((x),0,sizeof (x));
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<int,int> P;

const int maxv=1e6+300;
char r[maxv];
char s[maxv*2];
int p[maxv*2];
int n;
int len;
void manacher(){
    s[0]='&';
    for(int i=0;i<len;i++){
        s[2*i+1]='#';
        s[2*i+2]=r[i];
    }
    s[2*len+1]='#';
    s[2*len+2]='*';
    int mx=0,mxid=0;
    for(int i=1;i<=2*len;i++){
        if(mx>i){
            p[i]=min(p[mxid*2-i],mx-i);
        }else{
            p[i]=1;
        }
        for(;s[i-p[i]]==s[i+p[i]];p[i]++);
        if(p[i]+i>mx){
            mx=p[i]+i;
            mxid=i;
        }
    }
}


int T;
int cas;
int main(){
    freopen("/home/slyfc/CppFiles/in","r",stdin);
    //freopen("defense.in","r",stdin);
    //freopen("defense.out","w",stdout);
    cin>>T;
    while(T--){
        scanf("%s",r);
        len=strlen(r);
        manacher();
        int maxx=0;
        for(int i=len*2;i>=2;i--){
            if(p[i]==len*2-i+2) maxx=len*2-i+2;
        }
        maxx--;
        printf("Case %d: %d\n",++cas,2*len-maxx);
    }
    return 0;
}
View Code

 

posted @ 2015-10-15 22:42  PlusSeven  阅读(251)  评论(0编辑  收藏  举报