Manacher - 模板 - Palindrome POJ - 3974
题意:
多 组 测 试 用 例 , 每 组 包 括 一 个 长 度 为 l e n 的 字 符 串 , 求 该 字 符 串 的 最 大 回 文 子 串 ( 包 括 本 身 ) 的 长 度 。 多组测试用例,每组包括一个长度为len的字符串,求该字符串的最大回文子串(包括本身)的长度。 多组测试用例,每组包括一个长度为len的字符串,求该字符串的最大回文子串(包括本身)的长度。
Sample Input:
abcbabcbabcba
abacacbaaaab
END
Sample Output:
Case 1: 13
Case 2: 6
数据范围:
l
e
n
<
=
1000000
T
i
m
e
l
i
m
i
t
:
15000
m
s
,
M
e
m
o
r
y
l
i
m
i
t
:
65536
k
B
len<=1000000\\Time\ limit:15000 ms,Memory\ limit:65536 kB
len<=1000000Time limit:15000ms,Memory limit:65536kB
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=1000010;
char s[N];
char Ma[N*2]; //最大回文串+特殊符号
int Mp[N*2]; //Mp[i]:以i为中心的最大回文串长度+1
/* * abaaba *
i: 0 1 2 3 4 5 6 7 8 9 10 11 12 13
Ma[i]: $ # a # b # a # a $ b # a #
Mp[i]: 1 1 2 1 4 1 2 7 2 1 4 1 2 1 */
void Manacher(char s[],int len)
{
int l=0;
Ma[l++]='$';
Ma[l++]='#';
for(int i=0;i<len;i++)
{
Ma[l++]=s[i];
Ma[l++]='#';
}
Ma[l]=0;
int mx=0,id=0;
for(int i=0;i<l;i++)
{
Mp[i]=mx>i?min(Mp[2*id-i],mx-i):1;
while(Ma[i+Mp[i]]==Ma[i-Mp[i]])Mp[i]++;
if(i+Mp[i]>mx)
{
mx=i+Mp[i];
id=i;
}
}
}
int main()
{
int T=1;
while(~scanf("%s",s),strcmp(s,"END"))
{
int len=strlen(s);
Manacher(s,len);
int ans=0;
for(int i=0;i<2*len+2;i++)
ans=max(ans,Mp[i]-1);
printf("Case %d: %d\n",T++,ans);
}
return 0;
}