zoukankan      html  css  js  c++  java
  • 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
    */
    

      

  • 相关阅读:
    Docker
    Docker1.12服务发现,负载均衡和Routing Mesh
    Docker
    docker
    win7下构建swarm nodes实现跨host的容器之间的通信
    Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
    docker 1.12 版本 docker swarm 集群
    DotNet 资源大全中文版(Awesome最新版)
    Extended WPF Toolkit 新控件介绍
    ServiceStack Web Service 创建与调用简单示列
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10100253.html
Copyright © 2011-2022 走看看