//洛谷https://www.luogu.com.cn/problem/P3805
int d[22000007]; //二倍长度
char s[22000007];
int k=0,len,maxn=INT_MIN;
void manacher(char s[]){ //复杂度o(n)
d[1]=1;
for(int i=2,l=2,r=1;i<=k;i++){
if(l<=r) d[i]=min(d[l+r-i],r-i+1); //如果在框内,先更新
while( s[i-d[i]]==s[i+d[i]] )d[i]++; //暴力找右边
if(i+d[i]-1>r) l=i-d[i]+1,r=i+d[i]-1; //如果右边界超出当前盒子的右边界,更新盒子左右边界
maxn=max(maxn,d[i]);
}
}
void strInit(string str){ //根据原字符串str,创建一个新字符串,存到s数组中
s[0]='$',s[++k]='#';
for(int i=0;i<len;i++){
s[++k]=str[i];
s[++k]='#';
}
}
void solve(){
string str;
cin>>str;
len=str.size();
strInit(str);
manacher(s);
cout<<maxn-1<<"\n"; //原串最长回文子串=新串最长回文半径-1
}
![](https://img2023.cnblogs.com/blog/3142690/202312/3142690-20231213131307283-2019622488.png)