二分+字符串HASH
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
string a;
int n;
typedef unsigned long long ll;
ll p[1000005];
ll f[1000005];
ll rf[1000005];
bool chkp(ll mid)
{
for(int i=0;i<n;i++)
{
ll l1=i-mid,r1=i,l2=i,r2=i+mid;
if(l1<0||r1>=n||l2<0||r2>=n)
continue;
ll fl1;
ll rfr2;
if(l1==0)
fl1=0;
else
fl1=f[l1-1];
if(r2==n-1)
rfr2=0;
else
rfr2=rf[r2+1];
if(f[r1]-fl1*p[r1-l1+1]==rf[l2]-rfr2*p[r2-l2+1])
return 1;
}
return 0;
}
bool chkq(ll mid)
{
for(int i=0;i<n;i++)
{
ll l1=i-mid,r1=i-1,l2=i,r2=i+mid-1;
if(l1<0||l2<0||r1>=n||r2>=n)
continue;
ll fl1;
ll rfr2;
if(l1==0)
fl1=0;
else
fl1=f[l1-1];
if(r2==n-1)
rfr2=0;
else
rfr2=rf[r2+1];
if(f[r1]-fl1*p[r1-l1+1]==rf[l2]-rfr2*p[r2-l2+1])
return 1;
}
return 0;
}
int main()
{
int c=0;
while(cin>>a)
{
ll ansp=0,ansq=0;
if(a=="END")
break;
n=a.size();
p[0]=1;
f[0]=a[0]-'a'+1;
for(int i=1;i<n;i++)
{
f[i]=f[i-1]*(ll)27+(ll)(a[i]-'a'+1);
p[i]=p[i-1]*(ll)(27);
}
rf[n]=0;
for(int i=n-1;i>=0;i--)
{
rf[i]=rf[i+1]*27+(ll)(a[i]-'a'+1);
}
int l=1,r=n+1;
while(l<r)
{
int mid=l+r>>1;
if(chkp(mid))
{
ansp=mid;
l=mid+1;
}else
r=mid;
}
l=0,r=n+1;
while(l<r)
{
int mid=l+r>>1;
if(chkq(mid))
{
ansq=mid;
l=mid+1;
}else
r=mid;
}
printf("Case %d: %lld\n",++c,max(ansp*2+1,ansq*2));
}
return 0;
}
Manacher
#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
const int SIZE=1e6+10;
int len[2*SIZE];
char s[SIZE];
char str[SIZE*2];
int n=0;
int l=0;
void getstr()
{
int k=0;
str[k++]='@';
for(int i=0;i<n;i++)
str[k++]='#',str[k++]=s[i];
str[k++]='#';
str[k++]='0';
l=k;
}
int manacher()
{
int mx=0;
int id=0;
int ans=0;
for(int i=1;i<l;i++)
{
if(i<mx)
len[i]=min(mx-i,len[2*id-i]);
else
len[i]=1;
while(str[i+len[i]]==str[i-len[i]])len[i]++;
if(i+len[i]>mx)
{
mx=i+len[i];
id=i;
ans=max(ans,len[i]);
}
}
return ans-1;
}
int main()
{
int c=0;
int ans=0;
while(scanf("%s",s)&&s[0]!='E')
{
n=strlen(s);
getstr();
printf("Case %d: %d\n",++c,manacher());
}
return 0;
}