bzoj 2565: 最长双回文串

来源:互联网 发布:政府网站域名后缀 编辑:程序博客网 时间:2024/06/04 19:09

2565: 最长双回文串

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 2209  Solved: 1126
[Submit][Status][Discuss]

Description

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

Input

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

Output

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

Sample Input

baacaabbacabb

Sample Output

12


直接manacher+DP

不过要注意aba答案应该是2,因为组成双回文字符串的两个字符串长度必须都大于0

还有这题n的范围有问题。。。。不止100000

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int p[1000010], L[1000010], R[1000010];char s[500010], str[1000010];int main(void){int n, i, k, ans, mx, id;while(scanf("%s", s)!=EOF){n = strlen(s);memset(str, '\0', sizeof(str));str[0] = '$';str[1] = '#';for(i=0;i<=n-1;i++){k = (i+1)*2;str[k] = s[i];str[k+1] = '#';}n = k+1;s[n+1] = 0;mx = ans = 0;memset(L, 0, sizeof(L));memset(R, 0, sizeof(R));for(i=1;i<=n;i++){p[i] = 1;if(mx>i)p[i] = min(p[2*id-i], mx-i+1);while(str[i+p[i]]==str[i-p[i]])p[i]++;if(p[i]+i-1>mx){mx = p[i]+i-1;id = i;}R[i+p[i]-1] = max(R[i+p[i]-1], p[i]-1);L[i-p[i]+1] = max(L[i-p[i]+1], p[i]-1);}for(i=1;i<=n;i++)L[i] = max(L[i-1]-1, L[i]);for(i=n;i>=1;i--)R[i] = max(R[i+1]-1, R[i]);for(i=3;i<=n-2;i+=2)ans = max(ans, R[i]+L[i]);printf("%d\n", ans);}return 0;}