最长双回文串

Posted liguanlin1124

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最长双回文串相关的知识,希望对你有一定的参考价值。

题目大意:

输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分XY,(|X|,|Y|≥1)且XY都是回文串。

题解:
若X,Y都是回文串且相邻,则共用一个’#‘。

可以对于每个‘#’找出其左边界和右边界。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100050
char s0[N],s[2*N];
int l0,len;
int p[2*N],l[2*N],r[2*N];
void manacher()
{
    int mid=0,mx=0;
    for(int i=1;i<=len;i++)
    {
        if(i<=mx)p[i]=min(p[2*mid-i],mx-i+1);
        else p[i]=1;
        while(s[i+p[i]]==s[i-p[i]])p[i]++;
        l[i+p[i]-1]=max(p[i]-1,l[i+p[i]-1]);
        r[i-p[i]+1]=max(p[i]-1,r[i-p[i]+1]);
        if(i+p[i]-1>mx)
        {
            mid=i;
            mx=i+p[i]-1;
        }
    }
}
int main()
{
    scanf("%s",s0+1);
    l0 = strlen(s0+1);
    s[0]=!;
    for(int i=1;i<=l0;i++)
    {
        s[++len]=#;
        s[++len]=s0[i];
    }
    s[++len]=#;
    s[++len]=@;
    manacher();
    for(int i=3;i<=len;i+=2)
        r[i]=max(r[i],r[i-2]-2);
    for(int i=len;i>=1;i-=2)
        l[i]=max(l[i],l[i+2]+2);
    int ans = 0;
    for(int i=1;i<=len;i+=2)
        ans=max(ans,r[i]+l[i]);
    printf("%d
",ans);
    return 0;
}

 



以上是关于最长双回文串的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 2565: 最长双回文串

Tsinsen 最长双回文串

BZOJ2565:最长双回文串

最长双回文串

青橙 A1280. 最长双回文串

P4555 [国家集训队]最长双回文串