南二的公告牌
时间限制(普通/Java) :
2500 MS/ 7500 MS 运行内存限制 : 65536 KByte
总提交 : 470 测试通过 : 24
总提交 : 470 测试通过 : 24
比赛描述
南二有一个巨大的长方形公告牌,尺寸为h×w(h是它的高度,w是它的宽度)。牌子上可以张贴一切可能的告示:最近ACM程序设计竞赛通知,食堂菜单的变化,以及其他重要信息。
在9月1日,公告牌是空的。告示一个接一个地张贴在广告牌上。
每个告示是单位高度的纸条。具体地说,第i个告示是一个大小1 ×wi的矩形。当有人在公告牌上贴出一个新的告示,他永远选择尽可能上的位置。在所有可能的最高位置,她将永远选择最左边的一个。
如果没有有效的位置来贴一个新的告示,则不放在公告牌上。给定公告牌的大小,你的任务是找到告示放置的行数。
输入
输入文件的第一行包括三个整数:h, w, 和 n (1 ≤ h,w ≤ 109; 1 ≤ n ≤ 200 000) —表示公告牌的大小和告示的数目。
下面n行,每行包括一个整数wi (1 ≤wi ≤ 109) 表示 第i个告示的宽度。
输出
对于每个告示(按照它们在输入文件中给定的顺序)输出一个值 — 这个告示放置的行数。行从1到h标识,从顶行开始。如果一个告示不能放置于告示牌,则输出“-1”。
注意:输出部分的结尾要求包含一个多余的空行。
样例输入
3 5 5
2
4
3
3
3
样例输出
1
2
1
3
-1
题目来源
“IBM南邮杯”个人赛2009
#include<iostream>
#define MAX_N 1000000
using namespace std;
int h,w;
struct{
int l,r,num;
}node[MAX_N<<2];
void build(int i, int l, int r){
node[i].l = l;
node[i].r = r;
node[i].num = w;
if(l==r){
return;
}
int mid = (l+r)>>1;
build((i<<1)|1, l, mid);
build((i+1)<<1, mid+1, r);
}
int insert(int i, int wi){
if(node[i].num < wi){
return -1;
}
if(node[i].l==node[i].r){
node[i].num -= wi;
return node[i].l;
}
int result = insert((i<<1)|1, wi);
if(result == -1){
result = insert((i+1)<<1,wi);
}
if(result != -1){
node[i].num = max(node[(i<<1)|1].num, node[(i+1)<<1].num);
}
return result;
}
int main(){
int n,wi;
scanf("%d%d%d",&h,&w,&n);
build(0, 1, min(h,n));
while(n--){
scanf("%d",&wi);
printf("%d\n",insert(0,wi));
}
}