题意:有h×w大的公告板。有n条公告要写入,每条公告高度都是1,宽度是wi,每次从最上最左的空位写,假设有空位输出第几行。假设没有足够空位输出-1。
题解:注意h最大1e9。但事实上是看n的大小。由于假设有n条公告最多占n行,所以线段树最大是min(h,n)。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200005;
int h, w, n, sum[N << 2];
void pushup(int k) {
sum[k] = max(sum[k * 2], sum[k * 2 + 1]);
}
void build(int k, int left, int right) {
if (left == right) {
sum[k] = w;
return;
}
int mid = (left + right) / 2;
build(k * 2, left, mid);
build(k * 2 + 1, mid + 1, right);
pushup(k);
}
int query(int k, int left, int right, int x) {
if (left == right) {
sum[k] -= x;
return left;
}
int mid = (left + right) / 2, res = -1;
if (sum[k * 2] >= x)
res = query(k * 2, left, mid, x);
else if (sum[k * 2 + 1] >= x)
res = query(k * 2 + 1, mid + 1, right, x);
pushup(k);
return res;
}
int main() {
while (scanf("%d%d%d", &h, &w, &n) == 3) {
int temp = h < n ? h : n;
build(1, 1, temp);
int x;
for (int i = 0; i < n; i++) {
scanf("%d", &x);
if (x > w || sum[1] < x)
printf("-1
");
else
printf("%d
", query(1, 1, temp, x));
}
}
return 0;
}