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;
    }
  • 相关阅读:
    SRM 574 250 DIV2
    SRM 575 250 DIV2
    SRM 577 250 DIV2
    20181211-python1119作业郭恩赐
    20181207作业-郭恩赐
    python1119-20181206作业-郭恩赐提交
    python1119-20181205作业-郭恩赐提交
    python1119作业1-郭恩赐提交
    py1119_Linux学习_第二周总结
    小白都能看懂的block
  • 原文地址:https://www.cnblogs.com/ctlchild/p/4986909.html
Copyright © 2011-2022 走看看