Acwing139. 回文子串的最大长度(Manacher算法)

如果一个字符串正着读和倒着读是一样的,则称它是回文的。 给定一个长度为N的字符串S,求他的最长回文子串的长度是多少。

输入格式

输入将包含最多30个测试用例,每个测试用例占一行,以最多1000000个小写字符的形式给出。 输入以一个以字符串“END”(不包括引号)开头的行表示输入终止。

输出格式

对于输入中的每个测试用例,输出测试用例编号和最大回文子串的长度(参考样例格式)。 每个输出占一行。

输入样例:

abcbabcbabcba

abacacbaaaab

END

输出样例:

Case 1: 13

Case 2: 6


Manacher (马拉车)算法的简单应用

参考博客

挺有意思的一种计算最长回文串的算法,实现起来也较为简便,时间复杂度 O(n) ``` 

#include<bits/stdc++.h>
#define IL inline
#define ll long long
#define R register int

using namespace std;
const int N=2e6+5;//数组记得两倍大

int p[N];
char s[N],f[N];

IL int read()
{
    int f=1;char ch;
    while((ch=getchar())<'0'||ch>'9') if(ch=='-') f=-1;
    int res=ch-'0';
    while((ch=getchar())>='0'&&ch<='9') res=res*10+ch-'0';
    return f*res;   
}

int init(){
    int n=strlen(s+1);
    f[1]='@';f[2]='#';
    int j=2;
    for(R i=1;i<=n;++i){
        f[++j]=s[i];
        f[++j]='#';
    }
    f[++j]='$';
    return j;
}

int manacher(){
    int l=init();
    int ma=1,mx=0,id;
    for(R i=1;i<=l;++i){
        if(i<mx) p[i]=min(p[2*id-i],mx-i);
        else p[i]=1;
        while(f[i-p[i]]==f[i+p[i]]) p[i]++;
        if(mx<i+p[i]){
            id=i;
            mx=i+p[i];
        }
        ma=max(ma,p[i]-1);
    }
    return ma;
}

int main()
{
    int cnt=0;
    while(scanf("%s",s+1)&&s[1]!='E'){
        printf("Case %d: %d
",++cnt,manacher());
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/ljy-endl/p/14360387.html