在学校的入口处有一个巨大的矩形广告牌,高为h,宽为w。所有种类的广告都可以贴,比如ACM的广告啊,还有餐厅新出了哪些好吃的,等等。。
在9月1号这天,广告牌是空的,之后广告会被一条一条的依次贴上去。
每张广告都是高度为1宽度为wi的细长的矩形纸条。
贴广告的人总是会优先选择最上面的位置来帖,而且在所有最上面的可能位置中,他会选择最左面的位置,而且不能把已经贴好的广告盖住。
如果没有合适的位置了,那么这张广告就不会被贴了。
现在已知广告牌的尺寸和每张广告的尺寸,求每张广告被贴在的行编号。
Input
多组样例,不超过40个。
对每组样例,第一行包含3个整数h,w,n(1 <= h,w <= 10^9; 1 <= n <= 200,000) -广告牌的尺寸和广告的个数。
下面n行每行一个整数 wi (1 <= wi <= 10^9) - 第i张广告的宽度.
Output
对每张广告,输出它被贴在的行编号(是1到h之间的数),顶部是第一行。如果某广告不能被贴上,则输出-1。
Sample Input
3 5 5
2
4
3
3
3
Sample Output
1
2
1
3
-1
/************************************/
抱歉看错题了,这段话无用。代码是正确的。有时间重新写一遍
直接线段树会超时超内存。需要先进行离散化处理。
什么是离散化?大概是把较大的数映射为较小的数。比如区间【5,10】【20,30】如果不进行离散化处理,开数组至少为30个int字节【1,30】中其他的空间被浪费了。进行离散化处理后,每个数字根据与其他数字相对大小为标准进行映射。5->1,10->2,20->3,30->4。只需要开4个int大小的空间就够了。
然而这道题有些特殊。它的要求是”覆盖“。简单的离散后可能出现错误。
比如。【1,4】 【5,7】 【6,7】
线段树维护区间
/*****************************************/
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<string>
#include<stdlib.h>
#include<limits.h>
using namespace std;
/******************************************************/
#define LL long long int
#define mem(a,b) memset(a,b,sizeof(a))
#define mid (l+r)/2
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define L rt<<1
#define R rt<<1|1
#define N 200000+10
#define pow(a) a*a
#define INF 0x3f3f3f3f
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define lowbit(i) (i&-i)
/*********************************************************/
/*3 5 5
2
4
3
3
3*/
int h, w, n;
int MAX[N << 2];
int mark[N << 2];
int flag = 0;
int pos;
void pushup(int rt){
MAX[rt] = max(MAX[L], MAX[R]);
}
void update(int a, int l, int r, int rt){
if (l == r){
MAX[rt] -= a;
pos = l;
return;
}
if (MAX[L] >= a)update(a, lson);
else if (MAX[R] >= a)update(a, rson);
else return;
pushup(rt);
}
int main(){
while (~scanf("%d%d%d", &h, &w, &n)){
if (h > n) h = n;
for (int i = 1; i <= 4 * h; i++)MAX[i] = w;
while (n--){
int a; scanf("%d", &a);
if (MAX[1] < a)printf("-1\n");
else{
update(a, 1, h, 1);
printf("%d\n", pos);
}
}
}
}