最长回文双串
# 题意
给定一个字符串s,求s的最长回文双串t,即可将t分为两部分x,y 且x、y都是回文串
# 题解
在manacher 的基础上求st[i] 和 ed[i]
st[i] 表示以i为开头的回文串,ed[i]表示以i为结尾的回文串,
因为求的过程会遗漏,递推补全,最后枚举每一个'#'分割符即可
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=1e5+10; 4 char a[N],s[N*2]; 5 int n,mxr,mid,cnt; 6 int p[N*2],st[N*2],ed[N*2]; 7 inline void change() { 8 s[cnt] = '~', s[++cnt] = '#'; 9 for(int i=0;i<n;i++) 10 s[++cnt]=a[i],s[++cnt]='#'; 11 s[++cnt]='@'; 12 } 13 inline void manacher(){ 14 for(int i=1;i<=cnt;i++){ 15 if(i<mxr) p[i]=min(p[2*mid -i],mxr-i); 16 else p[i]=1; 17 while(s[i+p[i]] == s[i-p[i]]) ++p[i]; 18 if(mxr < i+p[i]) mxr=i+p[i],mid=i; 19 st[i-p[i]+1]=max(st[i-p[i]+1],p[i]-1); 20 ed[i+p[i]-1]=max(ed[i+p[i]-1],p[i]-1); 21 } 22 } 23 int main(){ 24 scanf("%s",a); 25 n=strlen(a); 26 change(); 27 manacher(); 28 for(int i=1;i<=cnt;i+=2) st[i]=max(st[i],st[i-2]-2); 29 for(int i=cnt;i>=1;i-=2) ed[i]=max(ed[i],ed[i+2]-2); 30 int ans=0; 31 for(int i=1;i<=cnt;i+=2) 32 if(st[i] && ed[i]) 33 ans=max(ans,st[i]+ed[i]); 34 printf("%d",ans); 35 }