题目:http://acm.hdu.edu.cn/showproblem.php?pid=2795
题意:
有一个h*w的公示栏和n条通知,要将n条通知贴到公示栏上,尽量
向上贴,然后输出每条通知在公示栏的哪行,如果贴不下则输出-1。
思路:
用线段树维护最大剩余的空间,如果能贴下,尽量向前贴。
#include <iostream>
#include <cstdio>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int maxn = 200005;
int tree[maxn<<2];
int h,w,n;
void PushUp(int rt){
tree[rt] = max(tree[rt<<1],tree[rt<<1|1]);
}
void build(int l, int r, int rt){
tree[rt] = w;
if (l == r)
return;
int m = (l + r) >> 1;
build (lson);
build (rson);
}
int id;
void update(int p, int l, int r, int rt){
if (l == r) {
tree[rt] -= p;
id = l;
return ;
}
int m = (l + r) >> 1;
if (tree[rt<<1] >= p)//尽量向左贴
update(p,lson);
else
update(p,rson);
PushUp(rt);
}
int main(){
while(~scanf("%d%d%d",&h,&w,&n)){
if(h > n) h = n;
build(1, h, 1);
int ann;
for(int i = 1;i <= n;i++){
scanf("%d",&ann);
if(tree[1]<ann)//贴不下
printf("-1\n");
else{
update(ann, 1, h, 1);
printf("%d\n",id);
}
}
}
return 0;
}