思路: 我们可以将每一行当成一个叶子节点,起初叶子节点的均为w,此时我们便将问题转化为维护区间区间最大值即可,想通了之后便是一道简单的线段树单点更新的题目~~~
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 222222;
int max_item[MAXN<<2];
int h, w, n, id;
inline int min(int a, int b)
{
return a < b ? a : b;
}
inline int max(int a, int b)
{
return a > b ? a : b;
}
void Push_Up(int rt)
{
max_item[rt] = max(max_item[rt<<1], max_item[rt<<1|1]);
}
void bulid(int l, int r, int rt)
{
if(l == r)
{
max_item[rt] = w;
return;
}
int m = (l + r)>>1;
bulid(l, m, rt<<1);
bulid(m + 1, r, rt<<1|1);
Push_Up(rt);
return ;
}
void update(int val, int l, int r, int rt)
{
if(l == r)
{
max_item[rt] -= val;
id = l;
return ;
}
int m = (l + r)>>1;
if(max_item[rt<<1] >= val)
update(val, l, m, rt<<1);
else
update(val, m + 1, r, rt<<1|1);
Push_Up(rt);
return ;
}
int main()
{
//freopen("aa.in", "r", stdin);
int t, t_w;
while(scanf("%d %d %d", &h, &w, &n) != EOF)
{
t = min(h, n);
bulid(1, t, 1);
for(int i = 1; i <= n; ++i)
{
scanf("%d", &t_w);
if(max_item[1] < t_w)
printf("-1\n");
else
{
update(t_w, 1, t, 1);
printf("%d\n", id);
}
}
}
return 0;
}