每次贴公告时都尽可能上
线段树中的val表示在[l,r]范围内黑板所剩的最大宽度
每次查询都先往左查询,这样就可以优先贴在靠上的地方
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
const int MAXN = 200005;
struct Node {
int l, r;
long long val;
int mid() { return (l + r) >> 1; }
}Tree[MAXN * 4];
int idx[MAXN];
void buildTree(int rt, int l, int r, long long w)
{
Tree[rt].l = l;
Tree[rt].r = r;
Tree[rt].val = w;
if (l == r)
{
idx[l] = rt;
return;
}
int m = Tree[rt].mid();
buildTree(rt << 1, l, m, w);
buildTree(rt << 1 | 1, m + 1, r, w);
}
void updata(int rt)
{
if (rt == 1)
return;
int parent = rt >> 1;
Tree[parent].val = max(Tree[parent << 1].val, Tree[parent << 1 | 1].val);
updata(parent);
}
long long ans;
void query(int rt, int w)
{
if (Tree[rt].val < w)
{
ans = -1;
return;
}
if (Tree[rt].l == Tree[rt].r)
{
ans = Tree[rt].l;
Tree[rt].val -= w;
updata(rt);
return;
}
if (Tree[rt << 1].val >= w)
query(rt << 1, w);
else
query(rt << 1 | 1, w);
}
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
int h, w, n;
while (cin >> h >> w >> n)
{
if (h > n)//h可能很大,但只有n个公告,最多也就只能用n这么高的黑板
h = n;
buildTree(1, 1, h, w);
while (n--)
{
cin >> w;
query(1, w);
cout << ans << endl;
}
}
return 0;
}