前两种情况显然直接manacher,对于第三种,枚举回文中心,二分回文半径,哈希判断即可。
1 #include<cstdio> 2 #include<algorithm> 3 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 4 using namespace std; 5 6 const int N=200010,P1=29,P2=998244353,P3=31,P4=1e9+7; 7 char A[N],B[N],s[N]; 8 int n,ans,pw1[N],pw2[N],hsa1[N],hsa2[N],hsb1[N],hsb2[N],pa[N],pb[N]; 9 10 int cal1(int l,int r,int hs[]){ return (hs[r]-1ll*hs[l-1]*pw1[r-l+1]%P2+P2)%P2; } 11 int cal2(int l,int r,int hs[]){ return (hs[r]-1ll*hs[l-1]*pw2[r-l+1]%P4+P4)%P4; } 12 13 void manacher(char a[],int p[],int hs1[],int hs2[]){ 14 s[0]='$'; s[1]='#'; int m=2*n+1,id=0,mxl=0; 15 rep(i,1,n) s[2*i]=a[i],s[2*i+1]='#'; 16 rep(i,1,m){ 17 p[i]=(i<mxl) ? min(p[id*2-i],mxl-i) : 1; 18 while (s[i+p[i]]==s[i-p[i]]) p[i]++; 19 if (p[i]+i>mxl) mxl=p[i]+i,id=i; 20 ans=max(ans,p[i]-1); 21 } 22 rep(i,1,n){ 23 hs1[i]=(1ll*hs1[i-1]*P1+a[i]-'A')%P2; 24 hs2[i]=(1ll*hs2[i-1]*P3+a[i]-'A')%P4; 25 } 26 } 27 28 void work(char a[],int pa[],int hsa1[],int hsa2[],char b[],int pb[],int hsb1[],int hsb2[]){ 29 rep(i,1,n){ 30 int t=pa[2*i]/2,L=t+1,R=min(i,n-i+1); 31 while (L<=R){ 32 int mid=(L+R)>>1; 33 if (cal1(i-mid+1,i-t,hsa1)==cal1(n-(i+mid-2)+1,n-(i+t-1)+1,hsb1) && cal2(i-mid+1,i-t,hsa2)==cal2(n-(i+mid-2)+1,n-(i+t-1)+1,hsb2)) 34 ans=max(ans,mid*2-1),L=mid+1; else R=mid-1; 35 } 36 if (i==n) continue; 37 t=pa[2*i+1]/2,L=t+1,R=min(i,n-i); 38 while (L<=R){ 39 int mid=(L+R)>>1; 40 if (cal1(i-mid+1,i-t,hsa1)==cal1(n-(i+mid-1)+1,n-(i+t)+1,hsb1) && cal2(i-mid+1,i-t,hsa2)==cal2(n-(i+mid-1)+1,n-(i+t)+1,hsb2)) 41 ans=max(ans,mid*2),L=mid+1; else R=mid-1; 42 } 43 } 44 } 45 46 int main(){ 47 freopen("palindrome.in","r",stdin); 48 freopen("palindrome.out","w",stdout); 49 scanf("%d%s%s",&n,A+1,B+1); reverse(B+1,B+n+1); 50 pw1[0]=pw2[0]=1; 51 rep(i,1,n) pw1[i]=1ll*pw1[i-1]*P1%P2,pw2[i]=1ll*pw2[i-1]*P3%P4; 52 manacher(A,pa,hsa1,hsa2); manacher(B,pb,hsb1,hsb2); 53 work(A,pa,hsa1,hsa2,B,pb,hsb1,hsb2); 54 work(B,pb,hsb1,hsb2,A,pa,hsa1,hsa2); 55 printf("%d ",ans); 56 return 0; 57 }