HDU 2795 Billboard (线段树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795

题目大意:有一块h*w的矩形广告板,要往上面贴广告;   然后给n个1*wi的广告,要求把广告贴上去; 而且要求广告要尽量往上贴并且尽量靠左;  求每个广告的所在的位置,不能贴则为-1。

用线段树模拟,要是左子树的最大值比当前广告大,就查询更新左子树,否则就右子树。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 const int MAXN = 2e5 + 5;
 6 struct segtree {
 7     int l , r , val;
 8 }T[MAXN << 2];
 9 int w , a[MAXN] , res;
10 
11 void init(int p , int l , int r) {
12     T[p].l = l , T[p].r = r;
13     int mid = (l + r) >> 1;
14     if(l == r) {
15         T[p].val = w;
16         return ;
17     }
18     init(p << 1 , l , mid);
19     init((p << 1)|1 , mid + 1 , r);
20     T[p].val = max(T[p << 1].val , T[(p << 1)|1].val);
21 }
22 
23 void query(int p , int val) {
24     if(T[p].l == T[p].r) {
25         T[p].val -= val;
26         res = T[p].l;
27         return ;
28     }
29     if(val <= T[p << 1].val) {
30         query(p << 1 , val);
31     }
32     else {
33         query((p << 1)|1 , val);
34     }
35     T[p].val = max(T[p << 1].val , T[(p << 1)|1].val);
36 }
37 
38 int main()
39 {
40     int h , n;
41     while(~scanf("%d %d %d" , &h , &w , &n)) {
42         h = min(h , n);
43         init(1 , 1 , h);
44         for(int i = 0 ; i < n ; i++) {
45             scanf("%d" , a + i);
46             if(T[1].val < a[i])
47                 printf("-1
");
48             else {
49                 query(1 , a[i]);
50                 printf("%d
" , res);
51             }
52         }
53     }
54 }
原文地址:https://www.cnblogs.com/Recoder/p/5351974.html