BZOJ4755: [JSOI2016]扭动的回文串——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4755
JYY有两个长度均为N的字符串A和B。一个“扭动字符串S(i,j,k)由A中的第i个字符到第j个字符组成的子串与B中的第j个字符到第k个字符组成的子串拼接而成。比如,若A=’XYZ’,B=’UVW’,则扭动字符串S(1,2,3)=’XYVW’。JYY定义一个“扭动的回文串”为如下情况中的一个:1.A中的一个回文串;2.B中的一个回文串;3.或者某一个回文的扭动字符串S(i,j,k)现在JYY希望找出最长的扭动回文串。
我是一个大sb看错题不然这题就很sb了而且我还对字符串一窍不通。
先写manacher预处理两个串每个点的最大回文串半径。
然后(以枚举A串上的回文中心i为例),显然i的回文串一定要包含i在A的最大回文串(因为如果舍弃一些A的话,则有可能剩下的一点无法和B匹配,故选i在A的最大回文串一定不会使答案变差。)
二分长度哈希即可。
#include<map> #include<cmath> #include<stack> #include<queue> #include<cstdio> #include<cctype> #include<vector> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef unsigned long long ll; const int N=2e5+5; const int B=666233; int n,ans,p[2][N]; char s1[N],s2[N]; ll ha[N],hb[N],qpow[N]; void manacher(char *s,int on){ s[0]='@'; for(int i=n;i>=1;i--)s[i<<1]=s[i]; for(int i=1;i<=2*n+1;i+=2)s[i]='#'; s[2*n+2]='?';int m=2*n+1; int mx=0,id; for(int i=1;i<=m;i++){ if(i<mx)p[on][i]=min(p[on][2*id-i],mx-i); else p[on][i]=1; while(s[i+p[on][i]]==s[i-p[on][i]])p[on][i]++; if(i+p[on][i]>mx){ mx=i+p[on][i];id=i; } ans=max(ans,p[on][i]-1); } } inline bool pan(int l1,int r1,int l2,int r2){ ll h1=ha[r1]-ha[l1-1]*qpow[r1-l1+1]; ll h2=hb[l2]-hb[r2+1]*qpow[r2-l2+1]; return h1==h2; } int main(){ scanf("%d%s%s",&n,s1+1,s2+1); manacher(s1,0);manacher(s2,1);n=2*n+1; qpow[0]=1; for(int i=1;i<=n;i++)qpow[i]=qpow[i-1]*B; for(int i=1;i<=n;i++)ha[i]=ha[i-1]*B+s1[i]; for(int i=n;i>=1;i--)hb[i]=hb[i+1]*B+s2[i]; for(int i=1;i<=n;i++){ int l=0,r=min(i-p[0][i],n-(i+p[0][i]-2)+1); while(l<r){ int mid=(l+r+1)>>1; int r1=i-p[0][i],l1=r1-mid+1,l2=i+p[0][i]-2,r2=l2+mid-1; if(pan(l1,r1,l2,r2))l=mid; else r=mid-1; } ans=max(ans,l+p[0][i]-1); } for(int i=1;i<=n;i++){ int l=0,r=min(i-p[1][i]+2,n-(i+p[1][i])+1); while(l<r){ int mid=(l+r+1)>>1; int r1=i-p[1][i]+2,l1=r1-mid+1,l2=i+p[1][i],r2=l2+mid-1; if(pan(l1,r1,l2,r2))l=mid; else r=mid-1; } int r1=i-p[1][i]+2,l1=r1-l+1,l2=i+p[1][i],r2=l2+l-1; ans=max(ans,l+p[1][i]-1); } printf("%d\n",ans); return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++