hdu-2715 Billboard

来源:互联网 发布:81端口活跃ip韩国破解 编辑:程序博客网 时间:2024/06/10 22:11

http://acm.hdu.edu.cn/showproblem.php?pid=2795


转:

题意:有一块板,规格为h*w,然后有n张海报,每张海报的规格为1*wi,选择贴海报的位置是:尽量高,同一高度,选择尽量靠左的地方。要求输出每张海报的高度位置。

因为最多只有二十万张海报,所以板的最大的长度不会超过二十万,但是要小心,如果板的长度小于h,我们还要用h来建树。起初在查询的时候并不直接去更新它,而是查询找出它的更新位置的后,再写个updata函数去更新,但是我们可以在查询到它的位置的时候,同时去更新当前点的剩余长度,然后回溯更新所有祖先区间。返回它的查询位置的时候,因为左儿子找到的位置是pos1,右儿子找到的位置是pos2,两者都赋初值为0,又因为每次查询只找出一个位置,也就是说pos1和pos2中只有一个被改变,另一个仍保持0,所以返回pos1+pos2是正确的。


#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define LL(x) (x<<1)#define RR(x) (x<<1|1)#define MID(a,b) (a+((b-a)>>1))#define INF (1<<30)const int N = 200005;struct node{int lft, rht, mx;int mid(){ return MID(lft, rht); }};int y[N], n, w, h;struct Segtree{node tree[N * 4];void build(int lft, int rht, int ind){tree[ind].lft = lft;tree[ind].rht = rht;tree[ind].mx = w;if (lft != rht){int mid = tree[ind].mid();build(lft, mid, LL(ind));build(mid + 1, rht, RR(ind));}}int updata(int valu, int ind){int lft = tree[ind].lft, rht = tree[ind].rht;if (lft == rht){tree[ind].mx -= valu;return lft;}else{int pos;if (tree[LL(ind)].mx >= valu)pos = updata(valu, LL(ind));elsepos = updata(valu, RR(ind));tree[ind].mx = max(tree[LL(ind)].mx, tree[RR(ind)].mx);return pos;}}}seg;int main(){while (scanf("%d%d%d", &h, &w, &n) != EOF){int tmp;seg.build(1,min(N,h),1);for (int i = 1; i <= n; i++){scanf("%d", &tmp);if (seg.tree[1].mx < tmp)puts("-1");else{printf("%d\n", seg.updata(tmp, 1));}}}return 0;}



0 0
原创粉丝点击