#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int MaxSize = 1001;
#define min(a, b) ((a) < (b) ?(a) : (b));
void Manacher(char *str,int *p)
{
int id;
int mx = 0;
int len = strlen(str);
for(int i = 0;i < len;i++)
{
if(mx > i)
{
p[i] = min(p[2 * id - i],p[mx - i]);
}
else
{
p[i] = 1;
}
for(;(str[p[i] + i] == str[p[i] - i]);p[i]++);
if(p[i] + i > mx)
{
mx = p[i] + i;
id = i;
}
}
}
注:
这是代码中最核心的一句话,它的作用是让我们在以i为中心向左右扩展时,尽量减少重复的比较,当mx > i 时会有两种情况。设j = 2 *id – i 以id为中心i的对称位置。
第一:当以i为中心的回文和以j为中心的回文都在以id为中心的回文中时。
由于回文的对称性,这时p[i]最小为p[j] 这是表达式前半部分。
第二:当以i为中心的回文或以j为中心的回文不在以id为中心的回文中时。
q a b a c a b a c
j id i
或:
c a b a c a b q c
j id i
这时以i为中心的最长回文不一定大于p[i],但是由于回文的对称性,他最小是mx-i(p[j]大时)或p[j]。