zoukankan      html  css  js  c++  java
  • zr#955 折纸

    分析

    我们发现行列独立

    只要分别求出答案然后相乘即可

    而对于所有行我们可以将其哈希后变为一行

    这样就转化为了1*n的问题

     代码

    #include<bits/stdc++.h>
    using namespace std;
    const int mod = 1e9+7;
    const int H = 233;
    string s[100100];
    int a[100100],b[100100],pre[100100],sur[100100],p[100100],d[300100];
    inline void getman(int a[],int n){
        int i,j,k,id=0,mx=1;
        for(i=1;i<=n;i++)d[i*2]=a[i],d[i*2+1]=-1;
        d[1]=-1,d[0]=-123,d[2*n+2]=-456;
        p[0]=1;
        for(i=1;i<=2*n+2;i++){
          p[i]=i<mx?min(p[2*id-i],mx-i):1;
          while(d[i-p[i]]==d[i+p[i]])p[i]++;
          if(i+p[i]>mx)id=i,mx=i+p[i];
        }
        for(i=1;i<=n;i++)p[i]=p[i*2+1]/2;
    }
    inline int work(int a[],int n){
        int i,j,k,ans=0;
        memset(pre,0,sizeof(pre));
        memset(sur,0,sizeof(sur));
        memset(p,0,sizeof(p));
        getman(a,n);
        k=0;
        for(i=1;i<n;i++)if(i-p[i]<=k)k=i,pre[i]=1;
        k=n;
        for(i=n-1;i>0;i--)if(i+p[i]>=k)k=i,sur[i]=1;
        k=1;
        for(i=1;i<n;i++){
          if(sur[i])ans+=k;
          if(pre[i])k++;
        }
        ans+=k;
        return ans;
    }
    int main(){
        int n,m,i,j,k;
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)cin>>s[i];
        for(i=1;i<=n;i++)
          for(j=m;j>0;j--)s[i][j]=s[i][j-1];
        for(i=1;i<=n;i++){
          for(j=1;j<=m;j++)a[i]=(1ll*a[i]*H%mod+(s[i][j]-'a'))%mod;
        }
        for(i=1;i<=m;i++){
          for(j=1;j<=n;j++)b[i]=(1ll*b[i]*H%mod+(s[j][i]-'a'))%mod;
        }
        printf("%lld
    ",1ll*work(a,n)*work(b,m));
        return 0;
    }
  • 相关阅读:
    软件架构感悟.
    浏览器缓存技术
    as到底干嘛了???
    关于WebForm开发问题(给新手的建议)
    疑难问题ASP.NET
    破解hash算法.高手请进,求解.
    (MVC和JVPL模式)Moon.Web架构谈
    Moon.NET框架架构及介绍
    调用API设置安卓手机的Access Point
    gtShell 为你常用的目录建立标签并快速跳转
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/11470855.html
Copyright © 2011-2022 走看看