给定一个字符串s,求s的最长回文双串t,即可将t分为两部分x,y 且x、y都是回文串
# 题解
在manacher 的基础上求 l 和 r 数组 l [ i ] 和 r [ i ] 分别表示 以 i 为轴心扩展出的回文串的左端点和右端点
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 5 using namespace std; 6 7 const int maxn=200010; 8 char a[maxn],s[maxn<<1]; 9 int l[maxn<<1],r[maxn<<1]; 10 int n,hw[maxn],ans; 11 inline void manacher() { 12 int maxright=0,mid; 13 for(int i=1; i<n; ++i) { 14 if(i<maxright) 15 hw[i]=min(hw[(mid<<1)-i],hw[mid]+mid-i); 16 else 17 hw[i]=1; 18 while(s[i+hw[i]]==s[i-hw[i]]) 19 ++hw[i]; 20 if(hw[i]+i>maxright) { 21 maxright=hw[i]+i; 22 mid=i; 23 } 24 } 25 } 26 27 void change() { 28 s[0]=s[1]='#'; 29 for(int i=0; i<n; ++i) { 30 s[i*2+2]=a[i]; 31 s[i*2+3]='#'; 32 } 33 n=n*2+2; 34 s[n]=0; 35 } 36 37 inline int maxx(int a,int b) { 38 return a>b?a:b; 39 } 40 41 int main() { 42 scanf("%s",a); 43 n=strlen(a); 44 change(); 45 manacher(); 46 int now=0; 47 for(int i=0; i<n; ++i) 48 while(now<=i+hw[i]-1) 49 l[now++]=i; 50 now=n; 51 for(int i=n-1; i>=0; --i) { 52 while(now>=i-hw[i]+1) 53 r[now--]=i; 54 } 55 int ans=0; 56 for(int i=0; i<n; ++i) 57 ans=maxx(ans,r[i]-l[i]); 58 printf("%d",ans); 59 }