[BZOJ4755][JSOI2016]扭动的回文串(manacher+Hash)

前两种情况显然直接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\n",ans);
56     return 0;
57 }

 

posted @ 2019-04-14 12:35  HocRiser  阅读(217)  评论(0编辑  收藏  举报