zoukankan      html  css  js  c++  java
  • BZOJ2565: 最长双回文串(回文树)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2565

    记录一下每个点往前最长延伸位置,正反两遍,枚举分割点。

    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #define rep(i,l,r) for (int i=l;i<=r;i++)
    #define down(i,l,r) for (int i=l;i>=r;i--)
    #define clr(x,y) memset(x,y,sizeof(x))
    #define ll long long
    #define maxn 100500
    using namespace std;
    int len[maxn],cnt[maxn],p1[maxn],p2[maxn],fail[maxn],s[maxn],to[maxn][30];
    int n,ans,tot,last,L,len1,len2;
    char ch1[maxn],ch2[maxn];
    void init(){
        len[tot=0]=0; len[++tot]=-1;
        fail[0]=1; s[n=0]=-1; last=0;
        clr(to,0);
    }
    void add(int c,int p[]){
        s[++n]=c;
        int tmp,cur,now;
        for (cur=last;s[n-len[cur]-1]!=c;cur=fail[cur]);
        if (!to[cur][c]){
            len[++tot]=len[cur]+2; now=tot;
            for (tmp=fail[cur];s[n-len[tmp]-1]!=c;tmp=fail[tmp]);
            fail[now]=to[tmp][c];
            to[cur][c]=now;
        } last=to[cur][c];
        cnt[last]++;
        p[n]=n-len[last]+1;
    }
    int main(){
        scanf("%s",ch1); L=strlen(ch1);
        rep(i,0,L-1) ch2[L-1-i]=ch1[i];
        init();
        rep(i,0,L-1) add(ch1[i]-'a',p1);
        init();
        rep(i,0,L-1) add(ch2[i]-'a',p2);
        rep(i,0,L-1){
            len1=i-p1[i]+1;
            len2=L-i-p2[L-i]+1;
            ans=max(ans,len1+len2);
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    python函数练习题2
    python函数练习题1
    数字是否是10的整数倍
    关于循环的作业:登陆程序
    用for循环写这段代码
    while循环语句
    在CentOS8 上安装Python3
    时隔半年再写购物车程序并改进
    vue上传
    根据生日计算年龄
  • 原文地址:https://www.cnblogs.com/ctlchild/p/4986909.html
Copyright © 2011-2022 走看看