传送门biu~
跑一边manacher计算
pi
p
i
表示以
i
i
点为对称中心的回文串的半径。再扫两遍求出和
ri
r
i
分别表示以
i
i
为尾的回文串的最小左端点和以为首的回文串的最大右端点。最后枚举
i
i
求和
li
l
i
的差即可。时间复杂度
O(n)
O
(
n
)
。
#include<bits/stdc++.h>
using namespace std;
int n,m,p[200005],l[200005],r[200005];
char s[100005],a[200005];
inline int manacher(){
m=2*n+1;
for(int i=1;i<=n;++i) a[2*i]=s[i],a[2*i+1]='#';
a[0]='+';a[1]='#';a[m+1]='-';
int Max=0,mid=0;
for(int i=1;i<=m;++i){
if(Max>=i) p[i]=min(p[mid*2-i],Max-i);
while(a[i+p[i]+1]==a[i-p[i]-1]) ++p[i];
if(i+p[i]>Max) Max=i+p[i],mid=i;
}
int now=1;
for(int i=1;i<=m;i+=2){
while(now+p[now]<i) ++now;
l[i]=2*now-i;
}
now=m;
for(int i=m;i>=1;i-=2){
while(now-p[now]>i) --now;
r[i]=2*now-i;
}
int re=0;
for(int i=1;i<=m;i+=2) re=max(re,r[i]-l[i]>>1);
return re;
}
int main(){
scanf("%s",s+1);n=strlen(s+1);
printf("%d\n",manacher());
return 0;
}