P3805 【模板】manacher算法

P3805 【模板】manacher算法

manacher

manacher算法:线性时间处理字符串中的最长回文串长度

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
using namespace std;
template <typename T> inline T min(T &a,T &b) {return a<b ?a:b;}
template <typename T> inline T max(T &a,T &b) {return a>b ?a:b;}
char a[11000003],b[22000008];
int p[22000008],n,ans;//p[i]:点i可扩展的最长回文串长度
int main(){
    scanf("%s",a); int len=strlen(a);
    for(int i=0;i<len;++i) b[n++]='#',b[n++]=a[i]; //在每个字符间插入一个特殊字符,同时处理长度为奇/偶的回文串
    b[n++]='#';
    int mx=-1,id=0; mx:目前处理出可拓展到右端点最右的回文串的右端点;id:右端点最右的回文串的中心
    for(int i=0;i<n;++i){
        p[i]= i<mx ? min(p[id*2-i],mx-i+1):1; //id*2-i: i关于id的对称点
        while(i+p[i]<n&&i-p[i]>=0&&b[i+p[i]]==b[i-p[i]]) ++p[i];
        if(i+p[i]-1>mx) mx=i+p[i]-1,id=i; //更新右端点最右的标记
        ans=max(ans,p[i]-1); //注意长度为p[i]-1(要去掉特殊字符)
    }printf("%d",ans);
    return 0;
}

 

posted @ 2018-09-27 11:21  kafuuchino  阅读(209)  评论(0编辑  收藏  举报