您的位置:首页 > 其它

HDU2795 Billboard(线段树)

2014-09-16 12:00 309 查看
题目链接:HDU2795.Billboard

在一个h * w的板子上贴n张海报,每张海报的面积是1 * wi,依次张贴。

要求尽量往上贴,同一行尽量往左贴,输出如果无法贴下输出-1。注意的是如果h过大的情况,因为最多20w张海报,所以如果h大于20w,就构建20w个叶子节点即可。边输入边更新即可。

稍微改了下自己的代码格式。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
#define lson l, mid, t<<1
#define rson mid+1, r, t<<1|1
#define MAX 200010
#define LL(x) (x << 1)
#define RR(x) (x << 1 | 1)
#define MID(x, y) (x + ((y - x) >> 1))
int a[MAX];
int w, h, n;
class segment_tree {
public :
int tree[MAX * 4];
void pushup(int t) {
tree[t] = w;
}
void build(int l, int r, int t) {
if(l == r) {
tree[t] = w; return;
}
int mid = MID(l, r);
build(lson), build(rson);
pushup(t);
}
int update(int c, int l, int r, int t) {
if(l == r) {
tree[t] -= c; return l;
}
else {
int ret;
int mid = MID(l, r);
if(tree[LL(t)] >= c) ret = update(c, lson);
else ret = update(c, rson);
tree[t] = max(tree[LL(t)], tree[RR(t)]);
return ret;
}
}
}seg;
int main() {
while(~scanf("%d%d%d", &h, &w, &n)) {
seg.build(1, min(h, MAX), 1);
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
if(seg.tree[1] < a[i]) printf("-1\n");
else printf("%d\n", seg.update(a[i], 1, min(h, MAX), 1));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: