题目大意:n个字符串,求每个字符串的最长子回文串。
回文串:正着读和反着读是相同。
题解:二分最长回文串的长度,hash判断是否是回文串。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define ull unsigned long long
#define N 1000002
const ull base=13331;
ull f1[N],f2[N],p[N];
char s[N];
int js;
int len;
ull get_hash_f1(int l,int r)
{
return f1[r]-f1[l-1]*p[r-l+1];
}
ull get_hash_f2(int l,int r)
{
return f2[r]-f2[l-1]*p[r-l+1];
}
bool check(int x)
{
for(int i=1;i+x-1<=len;i++)
{
int l1,r1,l2,r2;
l1=i;r1=i+x/2;
if(x&1){
}else r1--;
l2=i+x/2;
r2=i+x-1;
// if(js==4) cout<<x<<" "<<l1<<" "<<r1<<" "<<l2<<" "<<r2<<endl;
if(get_hash_f1(l1,r1)==get_hash_f2(len-r2+1,len-l2+1)) return true;
}
return false;
}
int main()
{
while(scanf("%s",s+1)&&strcmp(s+1,"END")!=0)
{
++js;
len=strlen(s+1);
p[0]=1;
memset(f1,0,sizeof(f1));
memset(f2,0,sizeof(f2));
for(int i=1;i<=len;i++)
{
f1[i]=f1[i-1]*base+(s[i]-'a'+1);
p[i]=p[i-1]*base;
}
reverse(s+1,s+len+1);
for(int i=1;i<=len;i++)
{
f2[i]=f2[i-1]*base+(s[i]-'a'+1);
}
int l,r,mid,ans;
l=0;r=len;
while(l<=r)
{
mid=(l+r)>>1;
//if(js==4) cout<<mid<<"----- "<<l<<"----- "<<r<<endl;
if(check(mid)) {l=mid+1;ans=mid;}
else if(check(mid+1)){ l=mid+2;ans=mid+1;}
else r=mid-1;
}
printf("Case %d: %d
",js,ans);
}
return 0;
}