题目大意:
有一块h*w的矩形广告板,要往上面贴广告;
然后给n个1*wi的广告,要求把广告贴上去;
而且要求广告要尽量往上贴并且尽量靠左;
求第n个广告的所在的位置,不能贴则为-1;
分析:
初学线段树不得不做的一个好题
利用线段树可以求区间的最大值;
将位置即h用来建树(h<=n,大了没有意义);
树中存储的为该位置还拥有的空间;
若左子树的最大值大于他,就查询左子树,否则查询右子树;
#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;
}