zoukankan      html  css  js  c++  java
  • bzoj 1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列——map+hash+转换

    Description

    N(1<=N<=100000)头牛,一共K(1<=K<=30)种特色,

    每头牛有多种特色,用二进制01表示它的特色ID。比如特色ID为13(1101),
    则它有第1、3、4种特色。[i,j]段被称为balanced当且仅当K种特色在[i,j]内
    拥有次数相同。求最大的[i,j]段长度。

    Input

    * Line 1: Two space-separated integers, N and K.

    * Lines 2..N+1: Line i+1 contains a single K-bit integer specifying the features present in cow i. The least-significant bit of this integer is 1 if the cow exhibits feature #1, and the most-significant bit is 1 if the cow exhibits feature #K.

    Output

    * Line 1: A single integer giving the size of the largest contiguous balanced group of cows.

    Sample Input

    7 3
    7
    6
    7
    2
    1
    4
    2

    INPUT DETAILS:

    The line has 7 cows with 3 features; the table below summarizes the
    correspondence:
    Feature 3: 1 1 1 0 0 1 0
    Feature 2: 1 1 1 1 0 0 1
    Feature 1: 1 0 1 0 1 0 0
    Key: 7 6 7 2 1 4 2
    Cow #: 1 2 3 4 5 6 7

    Sample Output

    4

    OUTPUT DETAILS:

    In the range from cow #3 to cow #6 (of size 4), each feature appears
    in exactly 2 cows in this range:
    Feature 3: 1 0 0 1 -> two total
    Feature 2: 1 1 0 0 -> two total
    Feature 1: 1 0 1 0 -> two total
    Key: 7 2 1 4
    Cow #: 3 4 5 6
    —————————————————————————————
    这道题的话 因为颜色一共最多有30种 转换成2进制 每一位代表一种颜色
    这样之后 如果存在 a1 b1 c1 d1 == a2 b2 c2 d2
    那么容易证明
    因为 d2-d1=c2-c1=b2-b1=a1-b1
    以d这一颜色为例 d2-d1=a2-a1
    所以 d2-a2==d1-a1 这样就转换成了只和自己有关
    那么每一位同理处理就可以了
    这样如果有两个前缀和 i 和 j 相同的话,那么i+1~j这一段的k种颜色出现次数一样多。
    这样处理之后加一波hahs和map 判断这种前缀时候存在以及他的位置就可以了
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<map>
    #define LL unsigned long long
    const int M=2e5+7,P=233;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int n,k,ans;
    int d[M][35];
    std::map<LL,int>q;
    int find(int x){
        LL sum=0;
        for(int i=2;i<=k;i++) sum=sum*P+1LL*d[x][i];
        if(!q[sum]&&sum) q[sum]=x;
        return q[sum];
    }
    int main(){
        n=read(); k=read();
        for(int i=1;i<=n;i++){
            int now=0,x=read();
            for(;x;x>>=1) d[i][++now]=x&1;
            for(int j=1;j<=k;j++) d[i][j]+=d[i-1][j];
        }
        for(int i=1;i<=n;i++){
            for(int j=2;j<=k;j++) d[i][j]-=d[i][1];
            ans=std::max(ans,i-find(i));
        }printf("%d
    ",ans);
        return 0;
    }
    View Code
     
  • 相关阅读:
    mysql 语句的查询过程解析
    postman 百度网盘下载 64位
    java 读取文内容(text,html)
    java把Word文件转成html的字符串返回出去
    spring boot 2.X上传文件限制大小
    nginx 做反向代理
    Linux下安装Redis
    微信小程序云开发个人博客项目实战(2)---引入-Vant-Weapp-小程序-UI-组件库
    微信小程序云开发个人博客项目实战(1)- 准备工作及引入 Vant Weapp 小程序 UI 组件库
    Video 视频播放防作弊和禁止下载
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7526274.html
Copyright © 2011-2022 走看看