朴素的找最长回文子串的算法要O(n^2) 而用后缀树组就要O(n log n)减少了很多
但是HDU3068特意卡了O(n log n)所以只能用O(n)复杂度的manacher算法写(虽然我是蒟蒻,也不会写后缀数组……)
不太会讲……直接贴代码
<span style="font-size:18px;">#include<cstdio>
#include<cstring>
#include<iostream>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
char s[300000];
int p[300000],mx,id,len,ans;
int main()
{
while(scanf("%s",s)!=EOF)
{
mx=0,id=0,ans=0;
len=strlen(s);
for(int i=len;i>=0;--i)
{
s[i*2+2]=s[i];
s[i*2+1]='#';
}
s[0]='$';len=len*2+1;
for(int i=1;i<=len;i++)//核心代码就是这个循环 看上去好像有两个循环嵌套 但实际上是O(n)
{
if(i<mx)p[i]=min(mx-i,p[2*id-i]);
else p[i]=1;
while(s[i-p[i]]==s[i+p[i]])p[i]++;
if(p[i]+i>mx)
{
mx=p[i]+i;
id=i;
}
}
for(int i=0;i<=len;i++)
ans=max(ans,p[i]);
printf("%d\n",ans-1);
}
return 0;
}</span>