HDU 2795 Billboard (线段树,单点查询)

HDU 2795


一个h*w的公告牌,要在其上贴公告,尽量往上,同一高度尽量靠左。求第n个广告所在的行数。没有合适的位置贴了则输出-1。

参考博客:http://blog.csdn.net/qiqi_skystar/article/details/50299743


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node {
	int l, r, m;
	int val;
};
int h, w, n;
node T[200100 << 2];
void build(int rt, int l, int r) {
	T[rt].val = w;
	T[rt].l = l;
	T[rt].r = r;
	T[rt].m = (l + r) >> 1;
	if(l == r) return;
	build(rt << 1, l, T[rt].m);
	build(rt << 1 | 1, T[rt].m + 1, r);
}
void query(int rt, int x) {
	if(T[rt].l == T[rt].r) {
		printf("%d\n", T[rt].l);
		T[rt].val -= x;
		return;
	}
	if(x <= T[rt << 1].val) {
		query(rt << 1, x);
	}
	else {
		query(rt << 1 | 1, x);
	}
	T[rt].val = max(T[rt << 1].val, T[rt << 1 | 1].val);
}
int main() {
    while(~scanf("%d %d %d", &h, &w, &n)) {
	    if(h > n) h = n;
	    build(1, 1, h);
	    while(n--) {
	    	int x;
	    	scanf("%d", &x);
	    	if(x > T[1].val) {
	    		printf("-1\n");
			}
			else {
				query(1, x);
			}
		}
	}
    return 0;
}



#include <bits/stdc++.h>
using namespace std;
struct node{
	int l, r, m;
	int val;
};
const int maxn = 200100;
int h, w, n, ans;
node T[maxn << 2];
int a[maxn];
void pushup(int rt)  {
	T[rt].val = max(T[rt << 1].val, T[rt << 1 | 1].val);
}
void build(int begin, int end, int rt) {
	T[rt].l = begin;
	T[rt].r = end;
	T[rt].m = (T[rt].l + T[rt].r) >> 1;
	if(begin == end) {
		T[rt].val = w;
		return ;
	}
	build(T[rt].l, T[rt].m, rt << 1);
	build(T[rt].m + 1, T[rt].r, rt << 1 | 1);
	pushup(rt);
}
void update(int add, int rt) {
	if(T[rt].l == T[rt].r) {
		T[rt].val -= add;
		printf("%d\n", T[rt].l);
		return ;
	}
	if(add <= T[rt << 1].val) update(add, rt << 1);
	else update(add, rt << 1 | 1);
	pushup(rt);
}
int main() {
	while(~scanf("%d %d %d", &h, &w, &n)) {
		if(h > n) h = n;  //解题关键 
		build(1, h, 1);
		int l;
		for(int i = 0; i < n; i++) {
			scanf("%d", &l);
			if(T[1].val < l) {
				puts("-1");
				continue;
			}
			update(l, 1);
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值