学一下manacher、、
主要思想就是利用回文的性质找对称点来往外扩
这个题还需要求双回文串、、就统计一下 从一个点往右的最长回文串长度 和 从一个点往左的最长回文串长度
再枚举断点即可
码:
#include<iostream>
#include<cstdio>
using namespace std;
#include<cstring>
#define N 500005
int k,s1[N],s2[N],i,n,p[N],max1;
char ch[N>>1],a[N];
void manacher()
{
k=0;
for(int i=1;i<=n;i++)
{
if(p[k]+k<i)
{
p[i]=0;
while(a[i+p[i]]==a[i-p[i]])p[i]++;
}else
{
p[i]=min(p[(k<<1)-i],p[k]+k-i);
while(a[i+p[i]]==a[i-p[i]])p[i]++;
}
if(k+p[k]<i+p[i])k=i;
}
}
int main()
{
// freopen("shu.in","r",stdin);
scanf("%s",ch+1);
a[n=0]='$';int len=strlen(ch+1);
for(i=1;i<=len;i++)
{
a[++n]='#';a[++n]=ch[i];
}
a[++n]='#';
a[n+1]='%';
manacher();
// for(i=1;i<=n;i++)cout<<a[i]<<" ";cout<<endl;
for(i=1;i<=n;i++)
{ // cout<<p[i]<<" ";
s1[i-p[i]+2]=max(p[i]-1,s1[i-p[i]+2]);
// if(i==8)cout<<p[i]-1<<"pp";
s2[i+p[i]-2]=max(p[i]-1,s2[i+p[i]-2]);
}
max1=1;
for(i=1;i<=n;i++)
{
if(a[i]=='#')continue;
max1-=2;
if(max1<1)max1=1;
max1=max(max1,s1[i]);
s1[i]=max1;
}
max1=1;
for(i=n;i>=1;i--)
{
if(a[i]=='#')continue;
if(max1>1)max1-=2;
max1=max(max1,s2[i]);
s2[i]=max1;
}
max1=1;
for(i=1;i<n-2;i++)
{
if(a[i]=='#')continue;
max1=max(s1[i+2]+s2[i],max1);
}
cout<<max1;
}