题目链接:HDU 2795 Billboard
线段树单点更新。
线段树记录某一行还剩下多少个空余位置,有空余位置的话先放左边那棵树。注意h的范围不会超过n的。
我感觉这道题有bug。。开始我写的是h = min(h, n),不通过,然后我看讨论版上有人说改成if(h > 200000) h = 200000,然后果然就过了,后来看了看别人代码,发现人家的min可以通过,但是输出-1时候要直接在main函数内判断,不能像我那样在函数里返回-1,诡异。
下面两份代码都是对的。
#include <iostream> #include <stdio.h> using namespace std; const int MAX_N = 200000 + 100; struct Node { int l, r, value; }; Node node[MAX_N << 2]; int h, w, n; void build(int l, int r, int i) { node[i].l = l; node[i].r = r; if(l == r) { node[i].value = w; return ; } int mid = (l + r) >> 1; build(l, mid, i << 1); build(mid + 1, r, i << 1 | 1); node[i].value = max(node[i << 1].value, node[i << 1 | 1].value); } int query(int i, int wi) { int res; if(node[i].l == node[i].r) { node[i].value -= wi; return node[i].l; } /*if(node[1].value < wi) return -1;*/ if(node[i << 1].value >= wi) res = query(i << 1, wi); else res = query(i << 1 | 1, wi); node[i].value = max(node[i << 1].value, node[i << 1 | 1].value); return res; } int main() { //freopen("in.txt", "r", stdin); while(scanf("%d%d%d", &h, &w, &n) != EOF) { h = min(h, n); /*if(h > MAX_N) h = MAX_N;*/ build(1, h, 1); int wi; for(int i = 0; i < n; i++) { scanf("%d", &wi); if(node[1].value < wi) { printf("-1\n"); continue; } printf("%d\n", query(1, wi)); } } return 0; }
#include <iostream> #include <stdio.h> using namespace std; const int MAX_N = 200000 + 100; struct Node { int l, r, value; }; Node node[MAX_N << 2]; int h, w, n; void build(int l, int r, int i) { node[i].l = l; node[i].r = r; if(l == r) { node[i].value = w; return ; } int mid = (l + r) >> 1; build(l, mid, i << 1); build(mid + 1, r, i << 1 | 1); node[i].value = max(node[i << 1].value, node[i << 1 | 1].value); } int query(int i, int wi) { int res; if(node[i].l == node[i].r) { node[i].value -= wi; return node[i].l; } if(node[1].value < wi) return -1; if(node[i << 1].value >= wi) res = query(i << 1, wi); else res = query(i << 1 | 1, wi); node[i].value = max(node[i << 1].value, node[i << 1 | 1].value); return res; } int main() { //freopen("in.txt", "r", stdin); while(scanf("%d%d%d", &h, &w, &n) != EOF) { //h = min(h, n); if(h > MAX_N) h = MAX_N; build(1, h, 1); int wi; for(int i = 0; i < n; i++) { scanf("%d", &wi); printf("%d\n", query(1, wi)); } } return 0; }