zoukankan      html  css  js  c++  java
  • [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
    ",ans);
    56     return 0;
    57 }
  • 相关阅读:
    The difference of the line-height:2 and line-height:2em
    Damao眼中的新媒体
    Damao教你如何使用MacDown
    SF Pro 项目中的css hack
    刷新一次,图片更换一次
    Markdown 初体验
    docker 部署gitlab 构建CI/CD流水线
    c#面向对象问题 WPF简单数据驱动
    WebApi的创建和调试(简单步骤)
    C语言实现的贪吃蛇小游戏
  • 原文地址:https://www.cnblogs.com/HocRiser/p/10655111.html
Copyright © 2011-2022 走看看