【BZOJ1702】[usaco2007margold]队列平衡

原来蛤习线性探测的时候要每次加一个稍大一点的数而不是每次+1……连蛤习都不会写,我tmd是有多弱

原题:

N(1<=N<=100000)头牛,一共K(1<=K<=30)种特色,
每头牛有多种特色,用二进制01表示它的特色ID。比如特色ID为13(1101),则它有第1、3、4种特色。
所以,我们认为第i头牛有第J个特色,那么整数k的二进制的第j位 肯定是 1.

[i,j]段被称为平衡当且仅当K种特色在[i,j]内拥有 次数相同。

求能够平衡的最大的[i,j]段的长度。

这题附近都是蛤习,所以就往蛤习方面想了

然后想了一段时间无果,决定看题解,看了几个题解都没看懂,但是受到启发,最终脑补出正解

首先每一位求一下前缀和,两组前缀和相减就可以求得一段区间内的个数,然后给相邻两个前缀和做差,如果有两组前缀和元素之间的差都相等,这两组前缀和做差就可以使中间的值相等

恩可以这么理解,如果两组前缀和元素之间的差相等,那么一组前缀的每个元素到另一组前缀和的对应元素的delta是一样的(因为从一组到另一组相对差没变),这两组前缀和减一下,每个元素的差都相等(感觉有点差分的意思?)

然后有一些细节需要注意

首先需要设置一组全部为零的前缀和或前缀和的差,因为可能出现某一组前缀和里面所有元素都相等,这个时候就要和0减

因为添加元素0进去了,这时候0就有意义了,hash的初值就不能设成0

以及蛤习线性探测的时候要每次加一个稍大一点的数而不是每次+1

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 int read(){int z=0,mark=1;  char ch=getchar();
 8     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)mark=-1;  ch=getchar();}
 9     while(ch>=‘0‘&&ch<=‘9‘){z=(z<<3)+(z<<1)+ch-‘0‘;  ch=getchar();}
10     return z*mark;
11 }
12 int n,m,s[110000][50];
13 int difference[110000][50];
14 int maxx=0;
15 int hash[510000],ha_top=159787;
16 bool check(int x,int y){
17     for(int i=2;i<=m;i++)  if(difference[x][i]!=difference[y][i])  return false;
18     return true;
19 }
20 int get_hash(int x){
21     int z=0;
22     for(int i=2;i<=m;i++)  z=(z+difference[x][i]*94406+5195)%ha_top;
23     while(hash[z]!=-1 && !check(hash[z],x)){  z+=283;  if(z>ha_top)z%=ha_top;}
24     if(hash[z]==-1){  hash[z]=x;  return x;}
25     return hash[z];
26 }
27 void get_s(int x,int y){  for(int i=1;y;i++,y>>=1)  s[x][i]+=y&1;}
28 int main(){//freopen("ddd.in","r",stdin);
29     memset(s,0,sizeof(s));
30     memset(difference,0,sizeof(difference));
31     memset(hash,-1,sizeof(hash));
32     cin>>n>>m;
33     get_hash(0);
34     for(int i=1;i<=n;i++){
35         get_s(i,read());
36         for(int j=1;j<=m;j++)  s[i][j]+=s[i-1][j],difference[i][j]=s[i][j]-s[i][j-1];
37         maxx=max(maxx,i-get_hash(i));
38     }
39     /*for(int i=1;i<=n;i++){
40         for(int j=1;j<=m;j++)  cout<<s[i][j]<<" ";
41         cout<<endl;
42     }
43     cout<<endl;
44     for(int i=1;i<=n;i++){
45         for(int j=1;j<=m;j++)  cout<<difference[i][j]<<" ";
46         cout<<endl;
47     }*/
48     cout<<maxx<<endl;
49     return 0;
50 }

时间: 2024-11-10 07:15:41

【BZOJ1702】[usaco2007margold]队列平衡的相关文章

探究一种定长队列操作(C语言版本)

一 问题来源:南京烽火通信面试 二 问题: 现有一种定长队列,长度为2的n次方,此队列可被多线程访问,但必须确保线程级安全,即在任意时刻,队列的长度保持不变. 三 笔者分析 1. 队列的存储结构--链式和顺序均可. 2. 长度为2的n次方--便于移动队头和队尾指针,假设队列长度为size,那么rear = (rear + 1) & (size - 1),&运算比算术求模运算效率高.为此,笔者使用了顺序队列. 3. 怎么确保线程级安全 笔者认为此系统一定同时存在多个读者和写者,读者是读取队头

珍藏好料开源放送: windows平台一个高性能、通用型的C++生产者/消费者架构模板

/* 生产者/消费者通用模板 特点: 高性能:采用多线程,多队列平衡的信号量等待模型,有效减少锁等待 可调节:可以根据实际应用环境调整队列数,最多可支持64个队列 使用简单,一个构造函数,一个生产函数,一个消费函数. */ #ifndef PANDC_H #define PANDC_H #include <vector> #include <deque> #include <Windows.h> #include <limits.h> using names

Linux基础命令---防火墙iptables

iptables iptables指令用来设置Linux内核的ip过滤规则以及管理nat功能.iptables用于在Linux内核中设置.维护和检查IPv4数据包过滤规则表.可以定义几个不同的表.每个表包含许多内置链,也可能包含用户定义的链.每个链都是一个规则列表,可以匹配一组数据包.每条规则都指定如何处理匹配的数据包.这被称为“目标”,它可能是跳转到同一表中的用户定义链. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fedora.   1.

bzoj1702[Usaco2007 Mar]Gold Balanced Lineup 平衡的队列*

bzoj1702[Usaco2007 Mar]Gold Balanced Lineup 平衡的队列 题意: N头牛,一共K种特色.每头牛有多种特色.[i,j]段被称为balanced当且仅当K种特色在[i,j]内拥有次数相同.求最大的[i,j]段长度.n≤100000,k≤30. 题解: 得到式子:a[i][l]-a[j][l]=a[i][l-1]-a[j][l-1],l在2..k之间,移项得a[i][l]-a[i][l-1]=a[j][l]-a[j][l-1],l在2..k之间,故可以定义一个

1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列

1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 510  Solved: 196[Submit][Status][Discuss] Description Farmer John's N cows (1 <= N <= 100,000) share many similarities. In fact, FJ has been able to narrow

【BZOJ】1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列

[题意]给定n头牛,k个特色,给出每头牛拥有哪些特色的二进制对应数字,[i,j]平衡当且仅当第i~j头牛的所有特色数量都相等,求最长区间长度. [算法]平衡树+数学转化 [题解]统计前缀和sum[i][j]表示前i头牛特色为j的数量,则区间i~j平衡需要满足: sum[j][1]-sum[i-1][1]=sum[j][2]-sum[i-1][2]=sum[j][3]-sum[i-1][3]=... 移项可得,只须 sum[j][1]-sum[j][2]=sum[i-1][1]-sum[i-1][

bzoj 1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列【hash】

我%&&--&()&%????? 双模hashWA,unsigned long longAC,而且必须判断hash出来的数不能为0???? 我可能学了假的hash 这个题求个前缀和,然后目标是找到距离当前位置最远,且能使这两个数组差分后2-k位相同 hash把差分后数组的2到k位压起来即可,用map存这个hash值最早出现的位置 但是我还是不明白为啥hash值不能为0啊?? #include<iostream> #include<cstdio> #i

[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 In

快速入门系列--WCF--06并发限流、可靠会话和队列服务

这部分将介绍一些相对深入的知识点,包括通过并发限流来保证服务的可用性,通过可靠会话机制保证会话信息的可靠性,通过队列服务来解耦客户端和服务端,提高系统的可服务数量并可以起到削峰的作用,最后还会对之前的事务知识做一定补充. 对于WCF服务来说,其寄宿在一个资源有限的环境中,为了实现服务性能最大化,需要提高其吞吐量即服务的并发性.然而在不进行流量控制的情况下,并发量过多,会使整个服务由于资源耗尽而崩溃.因此为相对平衡的并发数和系统可用性,需要设计一个闸门(Throttling)控制并发的数量. 由于