Billboard
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2795
解题思路:
题目大意:
有一块h*w的矩形广告板,要往上面贴广告; 然后给n个1*wi的广告,要求把广告贴上去; 而且要求广告要尽量往上贴并且尽量靠
左; 求第n个广告的所在的位置,不能贴则为-1。
算法思想:
利用线段树可以求区间的最大值,将位置即h用来建树(h<=n,大了没有意义),树中存储的为该位置还拥有的空间,若左子树的最大
值大于他,就查询左子树,否则查询右子树。
AC代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 200005;
struct node{
int l,r;
int num;
}tree[N<<2];
int h,w,n;
void build(int id,int l,int r){
tree[id].l = l;
tree[id].r = r;
tree[id].num = w;
if(l == r)
return ;
int mid = (l+r)>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
}
int query(int id,int len){
if(tree[id].l == tree[id].r){
tree[id].num -= len;
return tree[id].l;
}
else{
int sum1 = 0,sum2 = 0;
if(len <= tree[id<<1].num)
sum1 = query(id<<1,len);
else if (len <= tree[id<<1|1].num)
sum2 = query(id<<1|1,len);
tree[id].num = max(tree[id<<1].num,tree[id<<1|1].num);
return sum1+sum2;
}
}
int main(){
while(~scanf("%d%d%d",&h,&w,&n)){
if(h > n)
h = n;
build(1,1,h);
int x;
for(int i = 1; i <= n; i++){
scanf("%d",&x);
if(tree[1].num >= x)
printf("%d\n",query(1,x));
else
printf("-1\n");
}
}
return 0;
}