• BZOJ2565: 最长双回文串(Manacher)


    Description

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

    Input

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

    Output

    一行一个整数,表示最长双回文子串的长度。

    Sample Input

    baacaabbacabb

    Sample Output

    12

    解题思路:

    是求两个回文串相加的双回文最大长度。

    一直在想两个回文串相交的情况,结果发现是不存在的,那样只会形成更大的一个回文串,蒟蒻就是蒟蒻

    记录最右点和最左点。

    注意更新!!

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using std::min;
     5 using std::max;
     6 char a[1000000];
     7 int l[1000000];
     8 int ls[1000000];
     9 int rs[1000000];
    10 int f[1000000];
    11 int ans;
    12 int cnt;
    13 int main()
    14 {
    15     scanf("%s",a+1);
    16     int len=strlen(a+1);
    17     l[cnt]='&';
    18     for(int i=1;i<=len;i++)
    19     {
    20         l[++cnt]='&';
    21         l[++cnt]=a[i];
    22     }
    23     l[++cnt]='&';
    24     int mx=1;
    25     f[1]=1;
    26     for(int i=2;i<=cnt;i++)
    27     {
    28         f[i]=min(f[mx*2-i],f[mx]+mx-i);
    29         while(f[i]+i<=cnt&&l[f[i]+i]==l[i-f[i]])
    30             f[i]++;
    31         if(mx+f[mx]<i+f[i])
    32             mx=i;
    33         rs[f[i]+i-1]=max(rs[f[i]+i-1],f[i]-1);
    34         ls[i-f[i]+1]=max(ls[i-f[i]+1],f[i]-1);
    35     }
    36     for(int i=1;i<=cnt;i+=2)
    37         ls[i]=max(ls[i],ls[i-2]-2);
    38     for(int i=cnt;i>=1;i-=2)
    39         rs[i]=max(rs[i],rs[i+2]-2);
    40     for(int i=1;i<=cnt;i+=2)
    41         ans=max(ans,rs[i]+ls[i]);
    42     printf("%d
    ",ans);
    43     return 0;
    44 }
  • 相关阅读:
    2011Android技术面试整理附有详细答案(包括百度、新浪、中科软等多家公司笔试面试题)
    SQL注入攻击与防御
    从零开始学习jQuery
    linux内核定时器
    国内外 Java Script 经典封装
    jQuery EasyUI API 中文文档
    新手该怎么学习DIV+CSS网页标准布局?
    3种方法修改PHP时区
    linq教程
    BizTalk Server 系列文章目录
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9676762.html
Copyright © 2020-2023  润新知