分析
求最长回文子串不是manacher更牛¿
回文串分两类:
奇数长度和偶数长度。于是可以分类处理。
- 奇回文串 a [ 1 ] a[1] a[1]~ a [ ( m + 1 ) / 2 ] = r e v e r s e ( a [ ( m + 1 ) / 2 + 1 ] a[(m+1)/2]=reverse(a[(m+1)/2+1] a[(m+1)/2]=reverse(a[(m+1)/2+1] t o to to m ) m) m)
- 偶回文串 a [ 1 , ( m / 2 ) ] = r e v e r s e ( a [ ( m / 2 ) + 1 ] , m ) a[1,(m/2)]=reverse(a[(m/2)+1],m) a[1,(m/2)]=reverse(a[(m/2)+1],m) (","=to)
我们可以枚举每个回文串的中心位置,然后向两边扩展,看一下以
i
i
i为中心的最长回文串是多少。
然后:
- 满足条件的奇回文串答案长度为 2 ∗ m i d + 1 2*mid+1 2∗mid+1
- 满足条件的偶回文串答案长度为 2 ∗ m i d 2*mid 2∗mid
上代码
芜湖 这题调了两个钟终于感动天地。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
ll ans,lyr;
unsigned long long q[1000010],h[1000010],wx[1000010];
string s;
int main()
{
cin>>s;
lyr=0;
while(s!="END")
{
s=" "+s;
ll jq=s.length();
wx[0]=1ull;
q[0]=s[0]-97;
ans=0,lyr++;
for(ll i=1;i<=jq;i++)
{
wx[i]=wx[i-1]*131ull;
q[i]=q[i-1]*131ull+(s[i]-97);
}
h[jq]=0;
for(ll i=jq;i>=1;i--)
{
h[i]=h[i+1]*131ull+(s[i]-97);
}
for(ll i=1;i<=jq;i++)
{
ll l=0,r=jq,mid=0;
while(l<=r)
{
mid=(l+r)>>1;
if(i-mid-1<0||i+mid+1>jq)
{
r=mid-1;
continue;
}
else
{
if(q[i]-q[i-mid-1]*wx[mid+1]==h[i]-h[i+mid+1]*wx[mid+1])
{
l=mid+1;
ans=max(ans,mid*2+1);
}
else r=mid-1;
}
}
l=0,r=jq;
while(l<=r)
{
mid=(l+r)>>1;
if(i-mid<0||i+mid+1>jq)
{
r=mid-1;
continue;
}
else
{
if(q[i]-q[i-mid]*wx[mid]==h[i+1]-h[i+1+mid]*wx[mid])
{
l=mid+1;
ans=max(ans,mid*2);
}
else r=mid-1;
}
}
}
cout<<"Case "<<lyr<<": "<<ans<<endl;
cin>>s;
}
return 0;
}