#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll mod=1000000007;
const ll p=10000019;
const ll maxn=200010;
ll powp[maxn],h1[maxn],h2[maxn];
void init(){
powp[0]=1;
for(int i=1;i<maxn;i++){
powp[i]=(powp[i-1]*p)%mod;
}
}
void calh(ll h[],string &str){
h[0]=str[0];
for(int i=1;i<str.length();i++){
h[i]=(h[i-1]*p+str[i])%mod;
}
}
int calsinglesubh(ll h[],int i,int j){
if(i==0) return h[j];
return ((h[j]-h[i-1]*powp[j-i+1])%mod+mod)%mod;
}
int binarysearch(int l,int r,int len,int i,int iseven){
while(l<r){
int mid=(l+r)/2;
int h1l=i-mid+iseven,h1r=i;
int h2l=len-1-(i+mid),h2r=len-1-(i+iseven);//难!
int hashl=calsinglesubh(h1,h1l,h1r);
int hashr=calsinglesubh(h2,h2l,h2r);
if(hashl!=hashr) r=mid; //说明回文半径≤mid
else l=mid+1;
}
return l-1;
}
int main(){
init();
string str;
getline(cin,str);
calh(h1,str);
reverse(str.begin(),str.end());
calh(h2,str);
int ans=0;
//奇回文
for(int i=0;i<str.size();i++){
int maxlen=min(i,(int)str.length()-1-i)+1;
int k=binarysearch(0,maxlen,str.length(),i,0);
ans=max(ans,k*2+1);
}
//偶回文
for(int i=0;i<str.length();i++){
int maxlen=min(i+1,(int)str.length()-1-i)+1;
int k=binarysearch(0,maxlen,str.length(),i,1);
ans=max(ans,k*2);
}
printf("%d\n",ans);
return 0;
}
二分法求回文串
最新推荐文章于 2024-08-18 08:31:43 发布