小A的回文串(manacher模板)

小A非常喜欢回文串,当然我们都知道回文串这种情况是非常特殊的。所以小A只想知道给定的一个字符串的最大回文子串是多少,但是小A对这个结果并不是非常满意。现在小A可以对这个字符串做一些改动,他可以把这个字符串最前面的某一段连续的字符(不改变顺序)移动到原先字符串的末尾。那么请问小A通过这样的操作之后(也可以选择不移动)能够得到最大回文子串的长度是多少。
输入描述:
一行一个字符串表示给定的字符串S一行一个字符串表示给定的字符串S
输出描述:
一行输出一个整数,表示通过这样的操作后可以得到最大回文子串的长度。

示例1

输入

dcbaabc

输出

7

说明

将前面的dcba移动到末尾变成abcdcba,这个字符串的最大回文子串就是它本身,长度为7

备注:
N表示字符串的长度,1≤N≤5000N表示字符串的长度,1≤N≤5000

可用manacher求最长回文子串长度

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
char s[N],s2[N],s1[N<<1];
int Len[N<<1];
int init(char *s2,char *s)
{
   
    memset(s,0,sizeof(s));
    int i,len=strlen(s2);
    s[0]='@';
    for(i=1;i<=2*len;i+=2)
    {
   
        s[i]='#';
        s[i+1]=s2[i/2];
    }
    s[2*len+1]='#';
    s[2*len+2]='$';
    s[2*len+3]=0;
    return 2*len+1;
}
int manacher(char *s,int len)
{
   
    int p=0,ans=0,po=0;
    for(int i=1;i<=len;i++)
    {
   
        if(p>i)
            Len[i]=min(p-i,Len[2*po-i]);
        else
            Len[i]=1;
        while(s[i-Len[i]]==s[i+Len[i]])
            Len[i]++;
        if(Len[i]+i>p)
        {
   
            p=Len[i]+i;
            po=i;
        }
        ans=max(ans,Len[i]);
    }
    return ans-1;
}
int main()
{
   
    while(cin>>s1)
    {
   
        int len=strlen(s1);
        int maxlen=0;
        for(int i=0;i<len;i++)
        {
   
            strcpy(s2,s1+i);
            int len2=strlen(s2);
            for(int j=0;j<i;j++)
                s2[len2++]=s1[j];
            int len1=init(s2,s);
            int ans=manacher(s,len1);
            maxlen=max(ans,maxlen);
        }
        cout<<maxlen<<'\n';
    }
}

全部评论

相关推荐

点赞 评论 收藏
分享
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务