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

Posted y2823774827y

tags:

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

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

题目大意

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

建两个回文自动机,一个维护前缀,一个维护后缀

最后扫一遍更新答案

My complete code: 

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long LL;
const LL maxn=200000;
struct node{
    LL son[26],fail,len;
}tree1[maxn],tree2[maxn];
LL last,nod1,nod2,len,ans;
LL belong1[maxn],belong2[maxn];
char s1[maxn],s2[maxn];
inline void solve1(){
    s1[0]=‘#‘;
    tree1[0].fail=1; tree1[0].len=0;
    tree1[1].fail=0; tree1[1].len=-1;
    last=0;
    nod1=1;
    for(LL i=1;i<=len;++i){
        while(s1[i-tree1[last].len-1]!=s1[i])
            last=tree1[last].fail;
        if(!tree1[last].son[s1[i]]){
            tree1[++nod1].len=tree1[last].len+2;
            LL j=tree1[last].fail;
            while(s1[i-tree1[j].len-1]!=s1[i])
                j=tree1[j].fail;
            tree1[nod1].fail=tree1[j].son[s1[i]];
            tree1[last].son[s1[i]]=nod1;
        }
        last=tree1[last].son[s1[i]];
        belong1[i]=tree1[last].len;
    }
}
inline void solve2(){
    s2[0]=‘#‘;
    tree2[0].fail=1; tree2[0].len=0;
    tree2[1].fail=0; tree2[1].len=-1;
    last=0;
    nod2=1;
    for(LL i=1;i<=len;++i){
        while(s2[i-tree2[last].len-1]!=s2[i])
            last=tree2[last].fail;
        if(!tree2[last].son[s2[i]]){
            tree2[++nod2].len=tree2[last].len+2;
            LL j=tree2[last].fail;
            while(s2[i-tree2[j].len-1]!=s2[i])
                j=tree2[j].fail;
            tree2[nod2].fail=tree2[j].son[s2[i]];
            tree2[last].son[s2[i]]=nod2;
        }
        last=tree2[last].son[s2[i]];
        belong2[len-i+1]=tree2[last].len;
    }
}
int main(){
    scanf(" %s",s1+1);
    len=strlen(s1+1);
    for(LL i=1;i<=len;++i){
        s1[i]-=‘a‘;
        s2[len-i+1]=s1[i];
    }
    solve1();
    solve2();
    for(LL i=1;i<len;++i)
        if(belong1[i]+belong2[i+1]>ans)
            ans=belong1[i]+belong2[i+1];
    printf("%lld",ans);
    return 0;
}/*
baacaabbacabb
12
*/

  

以上是关于P4555 [国家集训队]最长双回文串的主要内容,如果未能解决你的问题,请参考以下文章

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

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

P4555 最长双回文串

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

备战省选

最长双回文串