mthoutai

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

题意:有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\n");
            else
                printf("%d\n", query(1, 1, temp, x));
        }
    }
    return 0;
}
posted on 2017-07-19 08:42  mthoutai  阅读(363)  评论(0编辑  收藏  举报