HDU 2795 Billboard(线段树)
2016-02-24 15:47
330 查看
题意:中文题
思路:建立一颗线段树,线段树维护的每个元素代表广告牌的一行的当前剩余最大空间。
最多只有n(n<=20W)个公共,且一条公共如果连一整行都放不下(即wi>w),直接输出-1即可。所以我们线段树最多只需要维护20W个元素。就算h有10亿,后面那些行根本是浪费。在输入的时候取最小就好了。
现在我们依次读入wi,找到能放下wi的序号最小的线段树叶节点,然后更新线段树即可。这个查询过程我们可以写query函数来查询。
其中线段树中节点维护的信息是:本节点控制的区间[L,R]内的叶节点的最大剩余空间maxv[i]。如果maxv[i]>wi说明这个节点的子树有叶子能放下wi,优先往左子树找即可.
Description
在学校的入口处有一个巨大的矩形广告牌,高为h,宽为w。所有种类的广告都可以贴,比如ACM的广告啊,还有餐厅新出了哪些好吃的,等等。。
在9月1号这天,广告牌是空的,之后广告会被一条一条的依次贴上去。
每张广告都是高度为1宽度为wi的细长的矩形纸条。
贴广告的人总是会优先选择最上面的位置来帖,而且在所有最上面的可能位置中,他会选择最左面的位置,而且不能把已经贴好的广告盖住。
如果没有合适的位置了,那么这张广告就不会被贴了。
现在已知广告牌的尺寸和每张广告的尺寸,求每张广告被贴在的行编号。
Input
多组样例,不超过40个。
对每组样例,第一行包含3个整数h,w,n(1 <= h,w <= 10^9; 1 <= n <= 200,000) -广告牌的尺寸和广告的个数。
下面n行每行一个整数 wi (1 <= wi <= 10^9) - 第i张广告的宽度.
Output
对每张广告,输出它被贴在的行编号(是1到h之间的数),顶部是第一行。如果某广告不能被贴上,则输出-1。
Sample Input
Sample Output
Hint
思路:建立一颗线段树,线段树维护的每个元素代表广告牌的一行的当前剩余最大空间。
最多只有n(n<=20W)个公共,且一条公共如果连一整行都放不下(即wi>w),直接输出-1即可。所以我们线段树最多只需要维护20W个元素。就算h有10亿,后面那些行根本是浪费。在输入的时候取最小就好了。
现在我们依次读入wi,找到能放下wi的序号最小的线段树叶节点,然后更新线段树即可。这个查询过程我们可以写query函数来查询。
其中线段树中节点维护的信息是:本节点控制的区间[L,R]内的叶节点的最大剩余空间maxv[i]。如果maxv[i]>wi说明这个节点的子树有叶子能放下wi,优先往左子树找即可.
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 200000+5; const int INF = 1e9; //线段树需要维护的信息 int sum[maxn*4]; #define lson i*2,l,m #define rson i*2+1,m+1,r //i结点收集子结点的统计结果 void PushUp(int i) { sum[i]=max(sum[i*2],sum[i*2+1]); } //递归建立线段树 void build(int i,int l,int r,int w) { sum[i]=w; if (l==r) { return; } int m = (l+r)/2; build(lson,w); build(rson,w); PushUp(i); //收集子结点的结果 } int query(int i,int l,int r,int u) { //目的区间包含当前区间 if (l==r) { sum[i]-=u; return l; } int m = (l+r)/2; int ans = (sum[i*2]>=u)?query(lson,u):query(rson,u); //优先左子树 PushUp(i); return ans; } int main() { int cas = 1; int n,h,w,N; while (scanf("%d%d%d",&h,&w,&N)!=EOF) { n = min(h,N); //确定维护的点数 build(1,1,n,w); while (N--) { int x; scanf("%d",&x); if (sum[1]<x) printf("-1\n"); else printf("%d\n",query(1,1,n,x)); } } }
Description
在学校的入口处有一个巨大的矩形广告牌,高为h,宽为w。所有种类的广告都可以贴,比如ACM的广告啊,还有餐厅新出了哪些好吃的,等等。。
在9月1号这天,广告牌是空的,之后广告会被一条一条的依次贴上去。
每张广告都是高度为1宽度为wi的细长的矩形纸条。
贴广告的人总是会优先选择最上面的位置来帖,而且在所有最上面的可能位置中,他会选择最左面的位置,而且不能把已经贴好的广告盖住。
如果没有合适的位置了,那么这张广告就不会被贴了。
现在已知广告牌的尺寸和每张广告的尺寸,求每张广告被贴在的行编号。
Input
多组样例,不超过40个。
对每组样例,第一行包含3个整数h,w,n(1 <= h,w <= 10^9; 1 <= n <= 200,000) -广告牌的尺寸和广告的个数。
下面n行每行一个整数 wi (1 <= wi <= 10^9) - 第i张广告的宽度.
Output
对每张广告,输出它被贴在的行编号(是1到h之间的数),顶部是第一行。如果某广告不能被贴上,则输出-1。
Sample Input
3 5 5
2
4
3
3
3
Sample Output
1
2
1
3
-1
Hint
相关文章推荐
- struts1保存上传图片及文件--Java类代码
- leetcode笔记--Count and Say
- Highcharts中文教程
- PDF文件页面的拆分方法
- nginx域名重定向 实现新旧域名过渡
- 关于mysql对字符串的数字的排序
- iOS开发通知那些事
- Java数据结构----图--最短路径解法Dijkstra算法和Floyd算法
- linux基本命令认识,shell打渠道包
- 总结及梳理 : Fragment
- 设计原则(安卓图片类)
- 混淆打包
- poj 1611 The Suspects
- Windows IOT 开发入门(准备工作)
- iOS 3D UI(3D翻转)
- 通过xib加载UITableViewCell的新方式
- STL next_permutation 和 prev_permutation
- PHP filesystem attack vectors
- PHP filesystem attack vectors - Take Two
- 开发监控Nginx RS节点状态的脚本