码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-12-11 11:26:36      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:let   hit   题目   更新   for   long   自动   blank   nbsp   

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 [国家集训队]最长双回文串

标签:let   hit   题目   更新   for   long   自动   blank   nbsp   

原文地址:https://www.cnblogs.com/y2823774827y/p/10100253.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!