HDU 2795 (线段树 单点更新) Billboard
h*w的木板,放进一些1*L的物品,求每次放空间能容纳且最上边的位子。
每次找能放纸条而且是最上面的位置,询问完以后可以同时更新,所以可以把update和query写在同一个函数里。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 const int maxn = 200000 + 10; 7 8 int _max[maxn << 2]; 9 int h, w, n, qL, qR, v; 10 11 void build(int o, int L, int R) 12 { 13 if(L == R) { _max[o] = w; return; } 14 int M = (L + R) / 2; 15 build(o*2, L, M); 16 build(o*2+1, M+1, R); 17 _max[o] = max(_max[o*2], _max[o*2+1]); 18 } 19 20 int query(int o, int L, int R) 21 { 22 if(L == R) { _max[o] -= v; return L; } 23 int M = (L + R) / 2; 24 int ans; 25 if(_max[o*2] >= v) ans = query(o*2, L, M); 26 else ans = query(o*2+1, M+1, R); 27 _max[o] = max(_max[o*2], _max[o*2+1]); 28 return ans; 29 } 30 31 int main() 32 { 33 //freopen("in.txt", "r", stdin); 34 35 while(scanf("%d%d%d", &h, &w, &n) == 3) 36 { 37 if(h > n) h = n; 38 build(1, 1, h); 39 for(int i = 0; i < n; i++) 40 { 41 scanf("%d", &v); 42 if(_max[1] < v) puts("-1"); 43 else printf("%d\n", query(1, 1, h)); 44 } 45 } 46 47 return 0; 48 }