bzoj2565最大双回文串

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

HINT

样例说明

  从第二个字符开始的字符串aacaabbacabb可分为aacaa与bbacabb两部分,且两者都是回文串。

数据规模及限制

  对于10%的数据,2≤|S|≤103。

  对于30%的数据,2≤|S|≤104。

  对于100%的数据,2≤|S|≤105。

 昨天看了stringoier的论文,学习了manacher的算法,这个算法的神奇之处在于避免了许多不必要的 操作。而这一题恰巧也灵活的使用了这个算法的思想。我最初的思想是

搞一个lef数组记录以当前点为结尾的最长回文串,rig数组记录以当前点为开头的最长回文串,时间复杂度O(n*n)

代码如下

 for(i=1;i<len;i++)

    {
        for (j=i;j<i+r[i];j++)
        {
           temp=j-i+1;
          if (temp>left[j])
                    left[j]=temp;
          }
        for (j=i;j>i-r[i];j--)
        {
              temp=i-j+1;
              if (temp>rig[j])
                    rig[j]=temp;
        }
    }
    for (i=1;i<len-1;i++)
         if (left[i]+rig[i+1]-1>ans)
             ans=left[i]+rig[i+1]-1;
后来无耻看了strongoier的论文和博客,以求lef数组为例,他维护了一个走的最右的区域,如果以当前点为中心的回文串没有先前点的回文串长,则没必要更新

代码如下

for(i=1,j=3;i<len;i++)

        for (;j<i+r[i];j++)
           // if(b[j]=='#')
                 c[j]=j-i;
    for (i=len-1,j=len-2;i>=1;i--)
         for (;j>=i-r[i]+1;j--)
            if (c[j])
                 c[j]+=i-j;
    for (i=1;i<len;i++)
         if (c[i]>ans)
             ans=c[i];


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值