回文子串的最大长度
题目描述
如果一个字符串正着读和倒着读是一样的,则称它是回文的。
给定一个长度为 \(N\) 的字符串 \(S\),求他的最长回文子串的长度是多少。
输入格式
输入将包含最多 \(30\) 个测试用例,每个测试用例占一行,以最多 \(1000000\) 个小写字符的形式给出。
输入以一个以字符串 'END' 开头的行表示输入终止。
输出格式
对于输入中的每个测试用例,输出测试用例编号和最大回文子串的长度(参考样例格式)。
每个输出占一行。
输入样例:
abcbabcbabcba
abacacbaaaab
END
输出样例:
Case 1: 13
Case 2: 6
Code:
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef unsigned long long ll;
const int N=1e6+5,P=131;
int n;
char s[N<<1],st[N];
ll h[N<<1],rh[N<<1],p[N<<1];
ll get(ll h[],int l,int r)
{
return h[r]-h[l-1]*p[r-l+1];
}
int main()
{
int Ca=0;
while(1)
{
scanf("%s",st+1);
if(st[1]=='E')break;
n=strlen(st+1);
for(int i=1;i<=n;++i)
{
s[2*i-1]=st[i];
s[2*i]='#';
}
s[2*n]='\0';
n<<=1;
// for(int i=1;i<=2*n;++i)
// putchar(s[i]);
p[0]=1;h[0]=rh[0]=0;
for(int i=1,j=n;i<=n;++i,--j)
{
h[i]=h[i-1]*P+s[i]-'a'+1;
rh[i]=rh[i-1]*P+s[j]-'a'+1;
p[i]=p[i-1]*P;
}
int ans=-1;
for(int i=1;i<=n;++i)
{
int l=1,r=min(i,n-i+1);
while(l<r)
{
int mid=(l+r+1)>>1;
if(get(h,i-mid+1,i)==get(rh,n-(i+mid-1)+1,n-i+1))l=mid;
else r=mid-1;
}
//i-l+1,i+l-1 2*l
if(s[i-l+1]=='#')ans=max(ans,l-1);
else ans=max(ans,l);
}
printf("Case %d: %d\n",++Ca,ans);
}
return 0;
}

浙公网安备 33010602011771号