#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 200010;
int Max[maxn<<2], w, h, n;
void pushup(int root){
Max[root] = max(Max[root<<1], Max[root<<1|1]);
}
void build(int root, int l, int r){
Max[root] = w; //初始化區間爲最大值
if (l == r) return;
int m = (l+r)>>1;
build(root<<1, l, m);
build(root<<1|1, m+1, r);
}
int query(int root, int l, int r, int key){ //query update 寫在一起
if (l == r){
Max[root] -= key;
return l;
}
int m = (l+r)>>1;
int res = (Max[root<<1] >= key)? query(root<<1, l, m, key):query(root<<1|1, m+1, r, key);
pushup(root);
return res;
}
int main(){
while(scanf("%d%d%d", &h, &w, &n) != EOF){
if (h > n)
h = n;
build(1, 1, h);
while (n--){
int x;
scanf("%d", &x);
if (Max[1] < x) // Max[1]存儲最大值
printf("-1\n");
else
printf("%d\n", query(1, 1, h, x));
}
}
return 0;
}
線段樹練習(3)hdu2795 Billboard
題目大意:
有一塊h*w的矩形廣告板,要往上面貼廣告;
然後給n個1*wi的廣告,要求把廣告貼上去;
而且要求廣告要儘量往上貼並且儘量靠左;
求第n個廣告的所在的位置,不能貼則爲-1;
分析:
初學線段樹不得不做的一個好題
利用線段樹可以求區間的最大值;
將位置即h用來建樹(h<=n,大了沒有意義);
樹中存儲的爲該位置還擁有的空間;
若左子樹的最大值大於他,就查詢左子樹,否則查詢右子樹;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.