正题
题目链接:https://www.luogu.com.cn/problem/P4555
题目大意
长度为nnn的串,双回文串的定义是两个连续的回文串,求最长的双回文串。
解题思路
我们用马拉车维护pip_ipi的时候维护一个lil_ili和rir_iri。
li:l_i:li:以iii开头的最长回文串
rir_iri以iii结尾的最长回文串。
然后ans=max{li+ri}(imod2=0)ans=max\{l_i+r_i\}(i\ mod\ 2=0)ans=max{li+ri}(i mod 2=0)
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e5+10;
int m,n,p[N],l[N],r[N],ans;
char s[N],a[N];
int main()
{scanf("%s",s+1);m=strlen(s+1);a[++n]='$';a[++n]='#';for(int i=1;i<=m;i++)a[++n]=s[i],a[++n]='#';s[++n]='&';int mid=0,mr=0;for(int i=1;i<=n;i++){if(i<mr) p[i]=min(p[mid*2-i],mr-i);else p[i]=1;while(a[i-p[i]]==a[i+p[i]])p[i]++;if(mr<i+p[i]) mr=i+p[i],mid=i;l[i+p[i]-1]=max(l[i+p[i]-1],p[i]-1);r[i-p[i]+1]=max(r[i-p[i]+1],p[i]-1);}for(int i=2;i<=n;i+=2)r[i]=max(r[i],r[i-2]-2);for(int i=n;i>=2;i-=2)l[i]=max(l[i],l[i+2]-2);for(int i=2;i<=n;i+=2)if(l[i]&&r[i])ans=max(ans,l[i]+r[i]);printf("%d",ans);
}