• bzoj2565 最长双回文子串


    Description

    顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同)。
    输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分XY,(|X|,|Y|≥1)且XY都是回文串。

    Input

    一行由小写英文字母组成的字符串S

    Output

    一行一个整数,表示最长双回文子串的长度。
     正反各运行一次manacher,同时求出以某个位置为左/右边界的最长回文串长度,最后扫描一次每个分界点取最大值。
    #include<cstdio>
    #include<cstring>
    char s[200010],s1[100010];
    int p[200010],p2[200010];
    int rx[200010];
    int lx[200010];
    inline int min(int a,int b){return a<b?a:b;}
    inline int maxs(int&a,int b){if(a<b)a=b;}
    int main(){
        scanf("%s",s1);
        int l=strlen(s1);
        for(int i=0;i<l;i++)s[i+i+2]=s1[i];
        l+=l;
        s[0]=1;
        s[l+1]=2;
        int mx=0,id=0;
        for(int i=2;i<=l;i++){
            if(i<mx)p[i]=min(p[(id<<1)-i],mx-i);
            else p[i]=1;
            maxs(rx[i],1);
            while(s[i+p[i]]==s[i-p[i]]){
                if(i+p[i]<=l)maxs(rx[i+p[i]],p[i]+1);
                ++p[i];
            }
            if(i+p[i]>mx){
                mx=i+p[i];
                id=i;
            }
        }
        mx=id=l+1;
        for(int i=l;i>=2;i--){
            if(i>mx)p2[i]=min(p2[(id<<1)-i],i-mx);
            else p2[i]=1;
            maxs(lx[i],1);
            while(s[i-p2[i]]==s[i+p2[i]]){
                if(i-p2[i]>=2)maxs(lx[i-p2[i]],p2[i]+1);
                ++p2[i];
            }
            if(i-p2[i]<mx){
                mx=i-p2[i];
                id=i;
            }
        }
        int ans=0;
        for(int i=3;i<l;i+=2)maxs(ans,lx[i+1]+rx[i-1]);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    selenium之 关闭窗口close与quit
    如何去掉xmind的备注红色下划线
    cmd里面快速粘贴复制的设置方式以及初始位置设置
    Python中的空格和缩进问题总结
    python 单例实现
    logging 简单使用
    CTypes
    类装饰器使用
    Django admin
    Django 视图
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5211355.html
Copyright © 2020-2023  润新知