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