zoukankan      html  css  js  c++  java
  • [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列

    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
    第一行给出数字N,K
    下面N行每行给出一个数字,代表这头牛的特征值

    Output
    求出一个区间值,在这个区间中,所有牛的这K种特征值的总和是相等的.

    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


    这题我们推推柿子,我们首先记录一下前缀和 sum[i][k],表示到第i头牛,k的特征值前缀和为k。如果说某段区间满足条件,那么肯定有(sum[r][i]-sum[l-1][i](iin[1,k]))都相同,我们单独拎出两项(sum[r][i]-sum[l-1][i]=sum[r][i-1]-sum[l-1][i-1]),移项得到(sum[r][i]-sum[r][i-1]=sum[l-1][i]-sum[l-1][i-1]),因此,我们只需要对每个点记录一下(sum[x][i]-sum[x][i-1]),而且由于我们按顺序枚举,那么最先出现的做左端点必定更优,这样我们就得到了判断第i个和第i-1个特征值相同的情况的办法了。判多个也只需要多次差分即可

    然后记录位置可以用map,当然,这题并不需要排序,因此可以用unordered_map,不过记得手写hash

    /*program from Wolfycz*/
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<unordered_map>
    #define inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x>=10)	print(x/10);
    	putchar(x%10+'0');
    }
    const int N=1e5,limit=2333;
    int n,k,Ans;
    struct S1{
    	int v[30];
    	S1(){memset(v,0,sizeof(v));}
    	bool operator ==(const S1 &x)const{
    		for (int i=1;i<k;i++)	if (v[i]!=x.v[i])	return 0;
    		return 1;
    	}
    }tmp;
    struct myHash{
    	size_t operator ()(const S1 &x)const{
    		ui res=0;
    		for (int i=1;i<k;i++)	res=res*limit+x.v[i];
    		return res;
    	}
    };
    unordered_map<S1,int,myHash>mp;
    int cnt[30];
    void Extract(int x){for (int i=0;i<k;i++)	cnt[i]+=x&1,x>>=1;}
    int main(){
    	n=read(),k=read(),mp[tmp]=0;
    	for (int i=1;i<=n;i++){
    		Extract(read());
    		for (int i=1;i<k;i++)	tmp.v[i]=cnt[i]-cnt[i-1];
    		if (mp.count(tmp))	Ans=max(Ans,i-mp[tmp]);
    		else	mp[tmp]=i;
    	}
    	printf("%d
    ",Ans);
    	return 0;
    }
    
  • 相关阅读:
    MD5加密
    input text 只能输入数字
    input date 支持placeholder属性
    实例表单的增改删
    jQuery 框架中$.ajax()的常用参数有哪些?
    jquery的相关属性和方法
    JS中实现继承的六种方式及优缺点
    c++类型转换
    c++动态内存与智能指针
    c++类的构造函数
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/9715313.html
Copyright © 2011-2022 走看看