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两部分,且两者都是回文串。
对于100%的数据,2≤|S|≤10^5
2015.4.25新加数据一组
Manacher练手题,主要思想是开一个len数组表示当前下标结尾最长的回文子串长度,这样就可以在Manacher的过程中一边匹配一边类似dp的统计答案了。代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 2e5 + 5;
int len[maxn << 1], RL[maxn << 1], mx, cnt;
char words[maxn], s[maxn << 1];
void Manacher() {
int Mr = 0, Mpos = 0, l, r;
for(register int i = 0; i < cnt; ++i) {
RL[i] = min(RL[(Mpos << 1) - i]/*对称位置*/, Mr - i/*长度超过目前范围*/);
for(;(l = i - RL[i]) >= 0 && (r = i + RL[i]) < cnt && s[l] == s[r]; ++RL[i]) {
if(l > 0) mx = max(mx, len[l - 1] + RL[i] * 2 + 1);
len[i + RL[i]] = max(len[i + RL[i]], RL[i] * 2 + 1);
}
--RL[i];
if(Mr < i + RL[i]) Mpos = i, Mr = i + RL[i];
}
}
int main() {
scanf("%s", words);
int sl = strlen(words);
for(register int i = 0; i < sl; ++i)
s[cnt++] = '#', s[cnt++] = words[i];
s[cnt++] = '#';
Manacher();
printf("%d", (mx + 1) / 2);
return 0;
}
rockdu
没有帐号? 立即注册