水和学术双贴因该没事八
link 感觉发题目版都没人会看
66code:
#7#8#14#15TLE
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
char s[11000010<<1],a[11000010];
int r[11000010<<1];//r是s[i]的最大回文半径
int len;
inline void change(){//manacher在每个字符后插入其他字符
len=strlen(a);
int cnt=0;s[cnt++]='$';s[cnt++]='#';//开始
for(int i=0;i<len;++i){
s[cnt++]=a[i];
s[cnt++]='#';//在每个字符后插入#
}
s[cnt++]='&';//标示结束
len=cnt;//更新长度
}
inline void manacher(){
int c=1,r1=0;//当前中心当前访问到的最远右端
for(int i=1;i<len;++i){//遍历
if(i>r1){//如果当前遍历点i在c左r右
//i的镜像点j即c*2-i
r[i]=min(r[c<<1-i],r[c]+c-i);
//r[i]再大也不会超过j点的回文即r[c*2-i]
//也不会超过r即r[c]+c-i
}else{//如果当前遍历点在r右
r[i]=1;//因为没有遍历过r外的情况,只能初始化为一
}
while(s[i-r[i]]==s[i+r[i]]) ++r[i];//暴力中心扩展
if(r[i]+i>r1){
r1=r[i]+i;
c=i;//更新r
}
}
}
int main(){
scanf("%s",a);
change();manacher();
int ans=-1;
for(int i=0;i<len;i++){
ans=max(ans,r[i]);
}
printf("%d",ans-1);
// cout<<ans-1<<endl;
//比如一个回文串是#a#a#a#a#a#
//这样若以中间的a为中心,其右边有k个a,k+1个#
//而这个回文串总共的a有k*2+1个,正好是其右边a的个数加上#的个数
//但是又因为是从1开始计数,hw把本身也算了进来,所以ans-1就是答案
return 0;
}