• 1247 排排站 USACO(查分+hash)


    /*
    暴力查分 n*n 
    */
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define maxn 100010
    using namespace std;
    int n,m,a[maxn],ans,p[maxn][31],r[31];
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
          scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
          for(int j=1;j<=m;j++)
            if((1<<j-1)&a[i])p[i][j]=p[i-1][j]+1;
            else p[i][j]=p[i-1][j];
        for(int i=1;i<=n;i++)
          for(int j=i+1;j<=n;j++)
            {
              int falg=0;
              for(int k=1;k<=m;k++)
                r[k]=p[j][k]-p[i-1][k];
              for(int k=2;k<=m;k++)
                if(r[k]!=r[k-1]){falg=1;break;}
              if(!falg)ans=max(ans,j-i+1);
            }
        printf("%d
    ",ans);
        return 0;
    }
    /*
    还是差分
    因为对于符合条件的序列
    有 sj0 - si0 = sj1 - si1 =...= sjk-1 - sik-1
    也就是说 如果存在i j 满足
      sj1 - sj0 == si1 - si0  
      sj2 - sj0 == si2 - si0  
           ......
      sjk-1 - sj0 == sik-1 - si0  
    我们定义c[i,j]=s[i,j]-s[i,0] 
    问题就转化成了 找隔得最远的ij 满足c[i] 和 c[j] 一样
    这里用hash加速查找 给每个c[i] 搞一个hash值 放到hash表里 
    */
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cstdlib>
    #define maxn 100010
    #define mod 999997
    using namespace std;
    int n,m,a[maxn],ans,p[maxn][35],c[maxn][35],has[maxn*10];
    int Get_hash(int *a)
    {
        int r=0;
        for(int i=0;i<m;i++)
            r=r%mod+a[i]<<2;
        if(r<0)r=-r;
        return r%mod;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
          scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
          for(int j=0;j<m;j++)
            if((1<<j)&a[i])p[i][j]=p[i-1][j]+1;
            else p[i][j]=p[i-1][j];
        for(int i=1;i<=n;i++)
          for(int j=0;j<m;j++)
            c[i][j]=p[i][j]-p[i][0];
        memset(has,-1,sizeof(has));
        has[0]=0;
        for(int i=1;i<=n;i++)
          {
              int k=Get_hash(c[i]);
              while(has[k]!=-1)
                {
                    int falg=0;
                    for(int j=0;j<m;j++)
                      if(c[has[k]][j]!=c[i][j])
                        {
                          falg=1;break;
                    }
                if(!falg&&i-has[k]>ans)
                  {
                      ans=i-has[k];break;
                  }
                k++;
              }
            if(has[k]==-1)has[k]=i;
          }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    使用Sharepoint Designer 无法打开站点提示错误403 forbidden
    英文Windows系统打开带中文TXT出现乱码
    Linux查看MegaSAS raid卡缓存策略
    PostgreSQL基础CRUD
    PostgreSQL安装(on Windows 10)
    Node.js安装(on Windows 10)
    Spring Data JPA:建立实体类
    Java:类加载
    Spring Data JPA:关联关系(外键)
    MySQL系统化知识概要
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5813796.html
Copyright © 2020-2023  润新知