【BZOJ4099】Trapped in the Haybales STL

【BZOJ4099】Trapped in the Haybales

Description

Farmer John has received a shipment of N large hay bales (1≤N≤100,000), and placed them at various locations along the road leading to his barn. Unfortunately, he completely forgets that Bessie the cow is out grazing along the road, and she may now be trapped within the bales!

Each bale j has a size Sj and a position Pj giving its location along the one-dimensional road. Bessie the cow can move around freely along the road, even up to the position at which a bale is located, but she cannot cross through this position. As an exception, if she runs in the same direction for D units of distance, she builds up enough speed to break through and permanently eliminate any hay bale of size strictly less than D. Of course, after doing this, she might open up more space to allow her to make a run at other hay bales, eliminating them as well.

Bessie can escape to freedom if she can eventually break through either the leftmost or rightmost hay bale. Please compute the total area of the road consisting of real-valued starting positions from which Bessie cannot escape.

农民约翰收到了N个干草包(1≤N≤100000),并将它们放置在一条道路上的

不同位置。不幸的是,他忘记了贝西是沿着道路放牧,她现在可能被困在干

草包里了!

每个包有一个大小Sj和位置Pj。贝西可以沿着道路自由走动,甚至可以

到达一捆草包所在的位置,但她必须通过这个位置。如果她向同一方向跑D单

位的距离,她就可以突破大小严格小于D的干草包。当然,这样做后她就可以

开发出更广阔的空间,突破其他干草包。

如果贝西可以突破最左边或最右边的干草包,她就可以重获新生。请计

算贝西无法逃脱的道路的面积。

Input

The first line of input contains N. Each of the next N lines describes a bale, and contains two integers giving its size and position, each in the range 1…10^9. All positions are distinct.

输入的第一行包含一个整数N。以下N行每行描述一捆干草包,包含两个

整数,分别表示它的大小和位置,每个数的范围是1...10^9。所有的位置是不同

的。

Output

Print a single integer, giving the area of the road from which Bessie cannot escape.

输出一个整数,表示贝西无法逃脱的道路面积。

Sample Input

5

8 1

1 4

8 8

7 15

4 20

Sample Output

14

题解:这种思路题果然难搞,无奈上官网看的题解。

如果我们将干草堆按坐标排序,对于某段区间[i,j],加入Bessie能突破[i+1,j-1]内的所有干草,但是就是突破不了[i,j],那就说明[i,j]里面一定没有比i,j更大的干草堆

因此,我们将干草堆按大小从大到小排序,一个一个加到坐标轴上,每加入一个干草堆,就找到它的前驱和后继,并分别判断这两段区间能否突破,如果不能,将区间标记一下就好了(我比较懒用的差分数组来打标记)

前驱后继可以用set来维护,但注意查询到前驱后继时我们还需要知道前驱后继的干草堆大小,这个记录一下排在第i位(按坐标排序)的干草堆编号就行了

#include <cstdio>
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
const int maxn=100010;
int h[maxn],x[maxn],rx[maxn],rh[maxn];
bool cmp1(int a,int b)
{
	return x[a]<x[b];
}
bool cmp2(int a,int b)
{
	return h[a]>h[b];
}
int s[maxn],sum;
int n,ref[maxn],ans;
set <int> ms;
int main()
{
	scanf("%d",&n);
	int i,j;
	for(i=1;i<=n;i++)	scanf("%d%d",&h[i],&x[i]),rx[i]=rh[i]=i;
		//rx,rh存储的其实是编号,我们是在将编号排序
	sort(rx+1,rx+n+1,cmp1);
	for(i=1;i<=n;i++)
	{
		ref[i]=x[rx[i]];
		x[rx[i]]=i;
	}
	sort(rh+1,rh+n+1,cmp2);
	set<int>::iterator it;
	for(i=1;i<=n;i++)
	{
		it=ms.lower_bound(x[rh[i]]);
		if(it!=ms.begin()&&!ms.empty())
		{
			it--;
			j=rx[*it];
			if(ref[x[rh[i]]]-ref[x[j]]<=min(h[rh[i]],h[j]))
			{
				s[x[j]]++;
				s[x[rh[i]]]--;
			}
		}
		it=ms.upper_bound(x[rh[i]]);
		if(it!=ms.end())
		{
			j=rx[*it];
			if(ref[x[j]]-ref[x[rh[i]]]<=min(h[rh[i]],h[j]))
			{
				s[x[rh[i]]]++;
				s[x[j]]--;
			}
		}
		ms.insert(x[rh[i]]);
	}
	for(i=1;i<=n;i++)
	{
		ans+=(sum>0)*(ref[i]-ref[i-1]);
		sum+=s[i];
	}
	printf("%d",ans);
	return 0;
}
时间: 2024-10-01 06:50:04

【BZOJ4099】Trapped in the Haybales STL的相关文章

【BZOJ4636】蒟蒻的数列 STL

[BZOJ4636]蒟蒻的数列 Description 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个数列,初始值均为0,他进行N次操作,每次将数列[a,b)这个区间中所有比k小的数改为k,他想知 道N次操作后数列中所有元素的和.他还要玩其他游戏,所以这个问题留给你解决. Input 第一行一个整数N,然后有N行,每行三个正整数a.b.k. N<=40000 , a.b.k<=10^9 Output 一个数,数列中所有元素的和 Sample Input 4

【BZOJ-4631】踩气球 线段树 + STL

4631: 踩气球 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 224  Solved: 114[Submit][Status][Discuss] Description 六一儿童节到了, SHUXK 被迫陪着M个熊孩子玩一个无聊的游戏:有N个盒子从左到右排成一排,第i个盒子里装着Ai个气球. SHUXK 要进行Q次操作,每次从某一个盒子里拿出一个没被踩爆的气球,然后熊孩子们就会立刻把它踩爆. 这M个熊孩子每个人都指定了一个盒子区间[Li, R

【转】next_permutation和prev_permutation(STL库中的全排列函数)用法

这是一个求一个排序的下一个排列的函数,可以遍历全排列,要包含头文件<algorithm> 下面是以前的笔记    与之完全相反的函数还有prev_permutation,查询当前排序上一个字典序.   返回为bool型,若返回true则成功生成,返回false则失败,还原到升序或降序的排列,与sort连用风味更佳   (1) int 类型的next_permutation   int main() {  int a[3]; a[0]=1;a[1]=2;a[2]=3;  do { cout<

HDU2072 单词数 【STL】+【strtok】

单词数 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 28045    Accepted Submission(s): 6644 Problem Description lily的好朋友xiaoou333最近很空,他想了一件没有什么意义的事情,就是统计一篇文章里不同单词的总数.下面你的任务是帮助xiaoou333解决这个问题. Inp

【转】由2个值组合成key的STL map排序问题

转自:http://blog.csdn.net/pathuang68/article/details/7526305 某网友问:"map中怎么设置多个key值进行排序?" 在C++中,map是典型的关联容器或者叫映射容器(associative container),其中的每一个元素都是由key-value这样成对出现的内容组成的,比如学号和学生之类具有一一对应关系的情形,学号可以作为key,学生对象可以作为key所对应的value.很显然这种情况下的key只有一个值,但是,在实际工作

C++STL之关联容器【map】【set】

map以键-值対的形式组织,键的作用在于索引,而值表示所存储和读取数据. set仅包含一个键,并且有效的支持某个键是否存在的查询. 他们都是基于标准型类库pair实现,该类型在utility头文件中. 一:关于pair类型的操作 pair<T1,T2> p1; //创建一个空pair类型 pair<T1,T2> p1(v1,v2); //创建并初始化 make_pair(v1,v2) //生成pair对象 <,>,==,!=  //类型之间比较,遵循字典序,先比较fir

【转】STL算法 &lt;algorithm&gt;中各种算法解析

原文:http://blog.csdn.net/tianshuai1111/article/details/7674327 一,巡防算法 for_each(容器起始地址,容器结束地址,要执行的方法) #include <iostream> #include <algorithm> #include <vector> using namespace std; template<class T> struct plus2 { void operator()(T&

【C++】【STL】二分查找函数

binary_search 这个函数的返回值是布尔型,也就是最简单的找到了就为真,没找到就是假. 传入参数有三个,数据集合的左端点,数据集合的右端点,查找的值. 注意这些左端点右端点是要求左开右闭原则的,就是和数学上的左开右闭区间[a, b)一样,右端点是个不会被查阅的值. 一般来说写法类似: bool flag = false; int data[n] = {...};///数据 sort(data, data + n); flag = binary_search(data, data + n

【转】【C++ STL】深入解析神秘的 --- 仿函数

原文:http://blog.csdn.net/tianshuai1111/article/details/7687983 一,概述        仿函数(functor),就是使一个类的使用看上去象一个函数.其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了. 有些功能的的代码,会在不同的成员函数中用到,想复用这些代码. 1)公共的函数,可以,这是一个解决方法,不过函数用到的一些变量,就可能成为公共的全局变量,再说为了复用这么一片代码,就要单立出一个函数