zoukankan      html  css  js  c++  java
  • hdu2795 Billboard ——线段树入门题

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

    题目大意:

      高度为h,长度为w的板子,贴n个海报,每个海报的高度都为1,长度由n个整数给出。贴海报的原则是,从高到低,优先选高的,从左到右,优先选右边的位置。起初每个海报在板子上所在的行数。

    题目思路:

      建立一棵叶子节点有h个的线段树,每个节点代表这个区间内的最大值,最开始,叶子节点都是w。然后每插入一个值就插入到叶子节点,输出叶子节点的值,然后更新父节点。

      这道题目的难点是,要想到建立线段树,把模型抽象出来。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cctype>
     6 #include <stack>
     7 #include <queue>
     8 #include <map>
     9 #include <set>
    10 #include <vector>
    11 #include <cmath>
    12 #include <algorithm>
    13 #define lson l, m, rt<<1
    14 #define rson m+1, r, rt<<1|1
    15 using namespace std;
    16 typedef long long int LL;
    17 const int MAXN =  0x3f3f3f3f;
    18 const int  MIN =  -0x3f3f3f3f;
    19 const double eps = 1e-9;
    20 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},
    21   {1,1},{1,-1},{-1,-1}};
    22 const int MAX = 200000+10;
    23 int a[MAX<<2], n, h, w, b[MAX];
    24 void pushup(int rt)
    25 {
    26   a[rt] = max(a[rt<<1], a[rt<<1|1]);
    27 }
    28 void build(int l, int r, int rt)
    29 {
    30   if (l == r) { a[rt] = w; return; }
    31   int m = (l + r) >> 1;
    32   build(lson); build(rson); pushup(rt);
    33 }
    34 void update(int p, int k, int l, int r, int rt)
    35 {
    36   if (l == r) { a[rt] -= k; return; }
    37   int m = (l + r) >> 1;
    38   if (p <= m) update(p, k, lson);
    39   else update(p, k, rson);
    40   pushup(rt);
    41 }
    42 int query(int k, int l, int r, int rt)
    43 {
    44   if (l == r) { return l; }
    45   int m = (l + r) >> 1, ret = 0;
    46   /*
    47   if (a[rt<<1] >= k) ret = query(k, lson);
    48   else ret = query(k, rson);
    49   */
    50   if (a[rt] >= k) {
    51     if (a[rt<<1] >= k) ret = query(k, lson);
    52     else ret = query(k, rson);
    53   }
    54   else return 0;
    55 
    56   return ret;
    57 }
    58 int main(void){
    59 #ifndef ONLINE_JUDGE
    60   freopen("hdu2795.in", "r", stdin);
    61 #endif
    62   int i, j, k;
    63   while (~scanf("%d%d%d", &h, &w, &n)){
    64     if (h > n) h = n;
    65     build(1, h, 1);
    66     for (i = 0; i < n; ++i) {
    67       scanf("%d", b + i);
    68       if (a[1] < b[i]) { printf("-1\n"); continue; }
    69       k = query(b[i], 1, h, 1);
    70       printf("%d\n", k); update(k, b[i], 1, h, 1);
    71     }
    72   }
    73 
    74   return 0;
    75 }

      注释掉的两行代码也是可以的,只不过是以前抄的NOTONLYSUCCESS的。其实思想是一样的。还是谢谢HH神牛,线段树就是看着他的博客学的。

  • 相关阅读:
    算法70----只有两个键的键盘【动态规划】
    Shell
    Shell
    Shell
    Shell
    Shell
    Tools
    Jenkins
    Java
    Product
  • 原文地址:https://www.cnblogs.com/liuxueyang/p/3039491.html
Copyright © 2011-2022 走看看