最长回文双串

最长回文双串


# 题意

给定一个字符串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 }

 

posted @ 2020-03-20 00:57  Hyx'  阅读(181)  评论(0编辑  收藏  举报