网上看到一个很不错的,所以自己就不写了。
链接:https://segmentfault.com/a/1190000003914228
但它的文章有一个小问题:第四幅图右边的蓝线应该是划分在红格的左边。
附例题:
Palindrome (POJ 3974)
题目链接: POJ 3974 http://poj.org/problem?id=3974
题目大意:
给定一个长为 n 的字符串,求它的最长回文子串。数据组数不超过30.
n <= 10^6
分析:
Manacher模板题
附代码
#include<iostream>
#include<cstring>
#include<string>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<cmath>
#include<queue>
#include<iomanip>
#include<set>
#include<cctype>
#include<algorithm>
using namespace std;
const int maxn=1e6+5;
int n,m,rl[maxn*2],T;
char t[maxn],s[maxn*2];
inline void manacher()
{
int pos=0,mx=0;
for(int i=1;i<=n;i++)
{
if(mx>i)
rl[i]=min(rl[2*pos-i],mx-i);
else
rl[i]=1;
while(s[i-rl[i]]==s[i+rl[i]])
rl[i]++;
if(rl[i]+i-1>mx)
{
mx=rl[i]+i-1;
pos=i;
}
}
}
int main()
{
//freopen("lx.in","r",stdin);
//freopen("lx.out","w",stdout);
while(scanf("%s",t+1),t[1]!='E')
{
m=strlen(t+1);
s[n=0]='!';
for(int i=1;i<=m;i++)
{
s[++n]='#';
s[++n]=t[i];
}
s[++n]='#';
s[n+1]='?';
manacher();
int ans=0;
for(int i=1;i<=n;i++)
if(rl[i]>ans)
ans=rl[i];
printf("Case %d: %d\n",++T,ans-1);
}
return 0;
}