南邮 OJ 1074 南二的公告牌

南二的公告牌

时间限制(普通/Java) :  2500 MS/ 7500 MS          运行内存限制 : 65536 KByte
总提交 : 470            测试通过 : 24 

比赛描述

南二有一个巨大的长方形公告牌,尺寸为h×w(h是它的高度,w是它的宽度)。牌子上可以张贴一切可能的告示:最近ACM程序设计竞赛通知,食堂菜单的变化,以及其他重要信息。

在9月1日,公告牌是空的。告示一个接一个地张贴在广告牌上。

每个告示是单位高度的纸条。具体地说,第i个告示是一个大小1 ×wi的矩形。当有人在公告牌上贴出一个新的告示,他永远选择尽可能上的位置。在所有可能的最高位置,她将永远选择最左边的一个。

如果没有有效的位置来贴一个新的告示,则不放在公告牌上。给定公告牌的大小,你的任务是找到告示放置的行数。



输入

输入文件的第一行包括三个整数:hw, 和 (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));
	}
}









你可能感兴趣的:(ACM,南邮OJ,南二的公告牌)