HDU 2795 Billboard(线段树:找到线段树中>=给定值的第一个元素位置 并 更新该点)
来源:互联网 发布:js 修改url参数 编辑:程序博客网 时间:2024/06/13 22:55
HDU 2795 Billboard(线段树:找到线段树中>=给定值的第一个元素位置 并 更新该点)
http://acm.hdu.edu.cn/showproblem.php?pid=2795
Problem Description
At the entrance to the university, there is a huge rectangular billboard of size h*w (h is its height and w is its width). The board is the place where all possible announcements are posted: nearest programming competitions, changes in the dining room menu, and other important information.
On September 1, the billboard was empty. One by one, the announcements started being put on the billboard.
Each announcement is a stripe of paper of unit height. More specifically, the i-th announcement is a rectangle of size 1 * wi.
When someone puts a new announcement on the billboard, she would always choose the topmost possible position for the announcement. Among all possible topmost positions she would always choose the leftmost one.
If there is no valid location for a new announcement, it is not put on the billboard (that's why some programming contests have no participants from this university).
Given the sizes of the billboard and the announcements, your task is to find the numbers of rows in which the announcements are placed.
On September 1, the billboard was empty. One by one, the announcements started being put on the billboard.
Each announcement is a stripe of paper of unit height. More specifically, the i-th announcement is a rectangle of size 1 * wi.
When someone puts a new announcement on the billboard, she would always choose the topmost possible position for the announcement. Among all possible topmost positions she would always choose the leftmost one.
If there is no valid location for a new announcement, it is not put on the billboard (that's why some programming contests have no participants from this university).
Given the sizes of the billboard and the announcements, your task is to find the numbers of rows in which the announcements are placed.
Input
There are multiple cases (no more than 40 cases).
The first line of the input file contains three integer numbers, h, w, and n (1 <= h,w <= 10^9; 1 <= n <= 200,000) - the dimensions of the billboard and the number of announcements.
Each of the next n lines contains an integer number wi (1 <= wi <= 10^9) - the width of i-th announcement.
The first line of the input file contains three integer numbers, h, w, and n (1 <= h,w <= 10^9; 1 <= n <= 200,000) - the dimensions of the billboard and the number of announcements.
Each of the next n lines contains an integer number wi (1 <= wi <= 10^9) - the width of i-th announcement.
Output
For each announcement (in the order they are given in the input file) output one number - the number of the row in which this announcement is placed. Rows are numbered from 1 to h, starting with the top row. If an announcement can't be put on the billboard, output "-1" for this announcement.
分析:
建立一颗线段树,线段树维护的每个元素(不是指树的节点哦)代表广告牌的一行的当前剩余最大空间maxv。比如i节点维护区间[l,r],那么r元素代表广告牌的第r行。即maxv[i]就是i节点维护的广告牌的那些行中,剩余空间的最大值。
最多只有n(n<=20W)个公共,且一条公共如果连一整行都放不下(即wi>w),直接输出-1即可。所以我们线段树最多只需要维护20W个元素。就算h有10亿,后面那些行根本是浪费。
注意:如果h比n小,那么线段树的节点总数定为h个,否则定位n个.如果wi>w,那么直接输出-1.
现在我们依次读入wi,找到能放下wi的序号最小的线段树叶节点,然后更新线段树即可。这个查询过程我们可以写query函数来查询,当然也可以用如下做法:将query嵌入update中。
其中线段树中节点维护的信息是:本节点控制的区间[L,R]内的叶节点的最大剩余空间maxv[i]。如果maxv[i]>wi说明这个节点的子树有叶子能放下wi,优先往左子树找即可.
本线段树不用query,只需要update并在update的时候返回需要的信息即可。
AC代码:2437ms
<span style="font-size:18px;"><span style="font-size:18px;">#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int H,W,n,Q;const int MAXN=200000+100;int maxv[MAXN*4];int id[MAXN*4];int cnt;#define lson i*2,l,m#define rson i*2+1,m+1,rvoid PushUp(int i){ maxv[i]=max(maxv[i*2] , maxv[i*2+1]);}void build(int i,int l,int r){ if(l==r) { maxv[i]=W; id[i]=++cnt; return ; } int m=(l+r)/2; build(lson); build(rson); PushUp(i);}int update(int w,int i,int l,int r){ if(w>maxv[i]) return -1; if(l==r) { maxv[i]-=w; return id[i]; } int res=-1; int m=(l+r)/2; if(maxv[i*2]>=w)res = update(w,lson); else if(maxv[i*2+1]>=w)res= update(w,rson); PushUp(i); return res;}int main(){ while(scanf("%d%d%d",&H,&W,&Q)==3) { cnt=0; n = min(Q,H);//线段树叶节点的最大数目 build(1,1,n); for(int i=1;i<=Q;i++) { int w; scanf("%d",&w); printf("%d\n",update(w,1,1,n)); } } return 0;}</span></span>
0 0
- HDU 2795 Billboard(线段树:找到线段树中>=给定值的第一个元素位置 并 更新该点)
- HDOJ 2795 Billboard(线段树—找到线段树中>=给定值的第一个点并更新这个点)
- hdu 2795 Billboard 线段树 点更新
- HDU 2795 Billboard (线段树 单点更新, 询问位置)
- HDU 2795 Billboard(线段树点更新)
- HDU 2795 Billboard 线段树 顺序点更新
- HDU-2795-Billboard(线段树 点更新求最值)
- hdu-2795Billboard(线段树 找到可以贴当前广告最上方的位置)
- HDU 2795 Billboard [线段树-单点更新]
- hdu 2795 Billboard 线段树 单点更新
- HDU 2795 Billboard / 线段树单点更新
- HDU-2795 Billboard 线段树单点更新
- hdu 2795 Billboard 线段树 单点更新
- hdu 2795 Billboard (线段树,单点更新)
- HDU-2795-Billboard-线段树单点更新
- HDU 2795 Billboard // 线段树 单点更新
- HDU 2795 Billboard 线段树单点更新
- HDU 2795 Billboard 线段树单点更新
- vs2010源代码管理里找不到vss的问题
- extjs form 取值 赋值 重置 1
- Android中的JSON解析方式:json; Gson ; Fastjson
- 对TCP三次而不是两次握手的理解
- repeater分页
- HDU 2795 Billboard(线段树:找到线段树中>=给定值的第一个元素位置 并 更新该点)
- 你想要的,要你自己给自己
- 2014_03_25
- Thread和Service应用场合的区别
- 使用第三方平台 ShareSDK 实现新浪微博的一键分享功能
- html5里面Models知识,说得比较单一,呵呵
- Struts2 - 122课
- 轻飘浮在忘忧河的上空
- android string.xml 空格和换行