题目描述
题解
这道题实际上是求不重叠且相邻的两个回文串拼在一起的最长长度。
将字符中间都插入#了之后问题转化为对于每一个#求它左边和右边回文串能覆盖到它的最远的回文中心。
这个满足单调性,求出以每一个点为对称中心的最长回文串了之后扫两遍就可以了。
代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 500005
char a[N],s[N];
int p[N],l[N],r[N],n,la,mx,id,now,ans;
int main()
{
gets(a);la=strlen(a);s[0]='*';
for (int i=0;i<la;++i)
s[++n]='#',s[++n]=a[i];
s[++n]='#';
for (int i=1;i<=n;++i)
{
if (mx>i) p[i]=min(p[2*id-i],mx-i);
else p[i]=1;
while (s[i-p[i]]==s[i+p[i]]) ++p[i];
if (i+p[i]>mx)
{
mx=i+p[i];
id=i;
}
}
now=1;
for (int i=1;i<=n;++i)
if (s[i]=='#')
{
while (now+p[now]<i) ++now;
l[i]=i-now;
}
now=n;
for (int i=n;i>=1;--i)
if (s[i]=='#')
{
while (now-p[now]>i) --now;
r[i]=now-i;
}
for (int i=1;i<=n;++i) ans=max(ans,l[i]+r[i]);
printf("%d\n",ans);
}