题目大意:
学校里有个公告栏,公告栏h*w面积,也就是高h,宽w。现在有一些广告需要贴,广告高度都是1,广告尽量往左,往上贴。给你n个广告,问你这个广告在第几层。
题目分析:
按照线段树的做法,首先利用h建树,每个结点存储的是该位置和剩余的空间,若左子树的最大值大于他,就查询左子树,否则查询右子树;父结点存储左右子节点的最大剩余值。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std ;
#define maxn 200005
#define L l,m,u<<1
#define R m+1,r,u<<1|1
int a[maxn<<2];
int h,w,n;
void build(int l,int r,int u){
a[u]=w;
if(r==l)
return ;
int m=(r+l)>>1;
build(L);
build(R);
}
int query(int x,int l,int r,int u){
if(l==r){
a[u]-=x;
return l;
}
int res;
int m=(l+r)>>1;
if(a[u<<1]>=x) res=query(x,L);
else res=query(x,R);
a[u]=max(a[u*2],a[u*2+1]);
return res;
}
int main(){
int x;
while(~scanf("%d%d%d",&h,&w,&n)){
if(h>n)
h=n;
build(1,h,1);
while(n--){
scanf("%d",&x);
if(a[1]<x)
printf("-1\n");
else
printf("%d\n",query(x,1,h,1));
}
}
return 0;
}