跳过正文
  1. Posts/

BZOJ 1637: [Usaco2007 Mar]Balanced Lineup (前缀和乱搞)

·3 分钟
目录

1637: [Usaco2007 Mar]Balanced Lineup
#

Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 503  Solved: 336 [Submit][Status][Discuss]

Description
#

Farmer John 决定给他的奶牛们照一张合影,他让 N (1 ≤ N ≤ 50,000) 头奶牛站成一条直线,每头牛都有它的坐标(范围: 0..1,000,000,000)和种族(0或1)。 一直以来 Farmer John 总是喜欢做一些非凡的事,当然这次照相也不例外。他只给一部分牛照相,并且这一组牛的阵容必须是“平衡的”。平衡的阵容,指的是在一组牛中,种族0和种族1的牛的数量相等。 请算出最广阔的区间,使这个区间内的牛阵容平衡。区间的大小为区间内最右边的牛的坐标减去最做边的牛的坐标。 输入中,每个种族至少有一头牛,没有两头牛的坐标相同。

Input
#

行 1: 一个整数: N 行 2..N + 1: 每行两个整数,为种族 ID 和 x 坐标。

Output
#

行 1: 一个整数,阵容平衡的最大的区间的大小。

Sample Input
#

7 0 11 1 10 1 25 1 12 1 4 0 13 1 22

Sample Output
#

11 输入说明

有7头牛,像这样在数轴上。

1 1 0 1 0 1 1 +–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 输出说明

牛 #1 (at 11), #4 (at 12), #6 (at 13), #7 (at 22) 组成一个平衡的最大的区间,大小为 22-11=11 个单位长度。

<——– 平衡的 ——–> 1 1 0 1 0 1 1 +–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

题意:有n头牛,在一个数轴上,没头牛有一个坐标x和性别(0或者1)

现在要选一段最长的连续区间使得区间内公牛和母牛的个数相等(区间的端点必须有牛存在才可以选),问最长区间是多少。

思路:乱搞。先按照x排序。把性别为0的换成-1,这样比较好处理平衡。然后分三种情况,包含左端点,包含右端点,两个端点都不包含。前两种情况随便搞。最后一种情况,我的做法是正反扫两遍预处理出了sum1[i]和sum2[i],sum1[i]表示正向性别和为i的最左端的点的id,sum2[i]表示反向性别和为i的最右端的点的id。

如果所有奶牛的性别和为total,那么对于正向扫的时候,设当前性别的前缀和为X,中间选的奶牛的前缀和为Z,最后不选的奶牛的性别和为Y,那么就有X+Y+Z=total.

我们要使得Z为0,所以Y=total-x. 说白了就是对于从左往右的每个i,找到最右端的某个点使得这两个点中间的奶牛(不包含这两个点)的性别和为0.

注意下标可能为负,所以整体平移一下就好。

然后三种情况取最大值。

时间复杂度O(n)

  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年04月08日 星期五 13时59分29秒
  4File Name :code/bzoj/1637.cpp
  5************************************************ */
  6
  7#include <cstdio>
  8#include <cstring>
  9#include <iostream>
 10#include <algorithm>
 11#include <vector>
 12#include <queue>
 13#include <set>
 14#include <map>
 15#include <string>
 16#include <cmath>
 17#include <cstdlib>
 18#include <ctime>
 19#define fst first
 20#define sec second
 21#define lson l,m,rt<<1
 22#define rson m+1,r,rt<<1|1
 23#define ms(a,x) memset(a,x,sizeof(a))
 24typedef long long LL;
 25#define pi pair < int ,int >
 26#define MP make_pair
 27
 28using namespace std;
 29const double eps = 1E-8;
 30const int dx4[4]={1,0,0,-1};
 31const int dy4[4]={0,-1,1,0};
 32const int inf = 0x3f3f3f3f;
 33const int N=1E5+7;
 34const int C=50000;
 35int total;
 36int ans;
 37int sum1[N],sum2[N];
 38int n;
 39struct node
 40{
 41    int sex;
 42    int x;
 43
 44    bool operator < (node b)const
 45    {
 46	return x<b.x;
 47    }
 48}a[N];
 49
 50int solve()
 51{
 52
 53    //三种情况,
 54    int cur =  0;
 55    int res2=-1;
 56    for ( int i = 1 ;i <= n ; i++)
 57    {
 58	cur += a[i].sex;
 59//	cout<<"cur:"<<cur<<endl;
 60	if (cur==0)
 61	    res2 = a[i].x-a[1].x;
 62    }
 63    int res3 = -1;
 64    cur = 0 ;
 65    for ( int i = n ;  i >= 1 ; i--)
 66    {
 67	cur +=a[i].sex;
 68	if (cur==0)
 69	    res3 = a[n].x - a[i].x;
 70    }
 71    ms(sum1,-1);
 72    cur = C ;
 73    for ( int i = 1 ;i <= n ; i++)
 74    {
 75	cur += a[i].sex;
 76	if (sum1[cur]==-1) sum1[cur] = i;
 77    }
 78    cur = C;
 79    ms(sum2,-1);
 80    for ( int i  = n ; i >= 1 ; i--)
 81    {
 82	cur += a[i].sex;
 83	if (sum2[cur]==-1) sum2[cur] = i;
 84    }
 85    int res= 0;
 86    cur = C;
 87    for ( int i = 1 ; i <= n-1 ; i++)
 88    {
 89	cur += a[i].sex;
 90	int Y = total - cur+C;
 91	if (Y>=0&&sum2[Y]!=-1&&a[sum2[Y]-1].x-a[i+1].x>0) res = max(res,a[sum2[Y]-1].x-a[i+1].x);
 92    }
 93
 94    res = max(res,res2);
 95    res = max(res,res3);
 96    return res;
 97}
 98int main()
 99{
100	#ifndef  ONLINE_JUDGE
101	freopen("code/in.txt","r",stdin);
102  #endif
103
104	ios::sync_with_stdio(false);
105	cin>>n;
106	total = 0 ;
107	for ( int i = 1 ; i <= n ; i++)
108	{
109	    cin>>a[i].sex>>a[i].x;
110	    if (a[i].sex==0) a[i].sex--;
111	    total += a[i].sex;
112	}
113	total += C;
114
115	sort(a+1,a+n+1);
116
117	cout<<solve()<<endl;
118
119
120
121  #ifndef ONLINE_JUDGE
122  fclose(stdin);
123  #endif
124    return 0;
125}

相关文章

codeforces #346 div 2 C. Tanya and Toys (暴力乱搞)

·2 分钟
题目链接 题意:有1E9个礼物,第i个礼物价钱是i,然后现在已经有n个不重复的礼物,a[i],m元钱,想尽可能多得买不同种类的礼物,还能买多少个。 思路:先不考虑已经买的,从1连续买到k,然后考虑子啊这个区间内已经买的,等于实际上没有花钱。 反正就是暴力搞啊搞啊。。我也不知道怎么搞。。 结果最后。。方案数为0的时候。。。最后一个答案我是单独输出的。。忘了判断了。。。所以会输出两个0.宝宝心里苦啊。。。。。。。。

前缀和问题总结

·2 分钟
There are two types of problems solvable by partial sum. 1.Problems which you are asked to answer some queries about the sum of a part of elements (without modify queries).

hdu 5416 CRB and Tree ( 2015 多校 #10 )

·2 分钟
http://acm.hdu.edu.cn/showproblem.php?pid=5416 # 题意:给出一棵树(n<=1E5),定义二元函数函数f(u,v) (u可以等于v)表示节点u到节点v经过的路径的权值的异或和。给出q组查询(q<=10),每组一个s,问有多少对无序点对(u,v)满足f(u,v)=s. 思路:类似codeforces #340 div 2 E XOR and Favorite Number 先dfs,处理出从根节点都任意节点的异或前缀和。然后对于每个询问o(n)扫一遍,统计sum[i]^s出现多少次。 总的时间复杂度为O(Tqn);