hdu 2795 Billboard (线段树,单点更新)

题意:

给出一个h*w的版面,现在要将每个海报(1*wi)贴到这上面,每次要选择最左边能够贴的地方!

题解:

其实n个点最多能用的高度就是n,那么可以根据搞当区间进行线段树,好吧我还是太水了。

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define B(x) (1<<(x))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
void cmax(int& a, int b){ if (b>a)a = b; }
void cmin(int& a, int b){ if (b<a)a = b; }
void cmax(ll& a, ll b){ if (b>a)a = b; }
void cmin(ll& a, ll b){ if (b<a)a = b; }
void add(int& a, int b, int mod){ a = (a + b) % mod; }
void add(ll& a, ll b, ll mod){ a = (a + b) % mod; }
#define lson rt<<1
#define rson rt<<1|1
const int oo = 0x3f3f3f3f;
const ll OO = 0x3f3f3f3f3f3f3f3f;
const ll MOD = 1000000007;
const double eps = 1e-9;
const int maxn = 210000;
struct SegTree{
	int l, r, len;
	int mid(){ return (l + r) >> 1; }
}tree[maxn << 2];

void push_up(int rt){
	tree[rt].len = max(tree[lson].len, tree[rson].len);
}

void build(int l, int r, int rt, int w){
	tree[rt].l = l;
	tree[rt].r = r;
	tree[rt].len = w;
	if (l == r) return;
	int mid = (l + r) >> 1;
	build(l, mid, lson, w);
	build(mid + 1, r, rson, w);
}

int query(int len, int rt){
	if (tree[rt].l == tree[rt].r){
		tree[rt].len -= len;
		return tree[rt].l;
	}
	int res = 0;
	if (len <= tree[lson].len)
		res = query(len, lson);
	else if (len <= tree[rson].len)
		res = query(len, rson);
	push_up(rt);
	return res;
}

int main(){
	//freopen("E:\\read.txt","r",stdin);
	int h, w, n;
	while (scanf("%d %d %d", &h, &w, &n) > 0){
		build(1, min(h, n), 1, w);
		for (int i = 1; i <= n; i++){
			scanf("%d", &w);
			if (tree[1].len >= w)
				printf("%d\n", query(w, 1));
			else
				printf("-1\n");
		}
	}
	return 0;
}



你可能感兴趣的:(hdu 2795 Billboard (线段树,单点更新))