看了notonlysuccess的博客
线段树维护最大值,这道题需要注意的是当h>n时,令h = n,原因是如果wi都小于w,最多只用前n行,反之一定结果是-1。
# include <cstdio> int h, w, n, wi; int m[4 * 200010]; int Max(int x, int y) { return x > y ? x : y; } void update(int r) { m[r] = Max(m[r << 1], m[r << 1 | 1]); } void build(int x, int y, int r) { m[r] = w; if (x >= y) return ; int mid = (x+y) >> 1, ls = r << 1, rs = r << 1 | 1; build(x, mid, ls); build(mid+1, y, rs); update(r); } void query(int x, int y, int r) { if (x == y) {m[r] -= wi; printf("%d\n", x); return ;} int mid = (x+y) >> 1, ls = r << 1, rs = r << 1 | 1; if (m[ls] < wi) query(mid+1, y, rs); else query(x, mid, ls); update(r); } void solve(void) { if (h > n) h = n; build(1, h, 1); while (n--) { scanf("%d", &wi); if (m[1] < wi) puts("-1"); else query(1, h, 1); } } int main() { while (~scanf("%d%d%d", &h, &w, &n)) solve(); return 0; }