本文仅是记录manacher算法的一个模板,并不对算法进行详细讲解
代码中的p数组表示以第i个点为中心所能扩展到的最长回文串,在新的串中首尾加一个不同字符可以防止其无限扩展,对于代码中的p[i]=min(p[id*2-i],maxn-i)表示因为id的左右是回文的所以对称,这里是求现在以i为中心,在目前所能扩展到底最远的范围内最长回文串的长度,之后进行暴力更新,不难得复杂度是O(n)
代码(hdu3068)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
char s1[310000],s2[310000];
int len1,len2,p[310000];
void init(){
s2[0]='#';
s2[1]='$';
for(int i=0;i<len1;i++){
s2[i*2+2]=s1[i];
s2[i*2+3]='$';
}
len2=len1*2+2;
s2[len2]='@';
}
void horsewithcar(){
int id=0,maxn=0;
for(int i=1;i<len2;i++){
if(maxn>i)p[i]=min(p[id*2-i],maxn-i);
else p[i]=1;
for(;s2[i+p[i]]==s2[i-p[i]];p[i]++)
if(i+p[i]>maxn){
maxn=i+p[i];
id=i;
}
}
}
int main()
{ int n,m,i,j,k;
while(scanf("%s",s1)!=EOF){//我也不知道为啥hdu上不加!=EOF会tle
len1=strlen(s1);
init();
horsewithcar();
int ans=0;
for(i=1;i<len2;i++)
ans=max(ans,p[i]);
cout<<ans-1<<endl;
}
return 0;
}