• HDU_2795 Billboard(线段树)


     

     /*题意:输出每次贴上的海报所在的行号,行号为1...h;

    开始拿到这题没思路,后来问了问本校的大牛,终于找到思路。这题是按high建树,
    结构体中定义一个len变量,存放当前该结点的空闲长度。某结点的父结点存放其子结
    点的最大空闲长度值;

    比如(len = 10):

    1

    len = max(len2,len3)

    /   \

    2 3

    (len = max(len4,len5))

    / \ / \

    4 5 6 7

    (len = 6) (len = 7)

    这样每次更新时,如果父结点的node[t].len < w,则父结点之下的结点都不符合条件,
    可以跳过。
    */

    /*My Code:*/

    #include
    <iostream>
    #include
    <cstdio>
    #define L(t) t << 1
    #define R(t) t << 1 | 1

    using namespace std;

    const int N = 200005;

    struct node
    {
    int l, r;
    int w;
    }node[N
    *4];

    int w, ans;

    void creat(int t, int l, int r)
    {
    node[t].l
    = l;
    node[t].r
    = r;
    node[t].w
    = w;

    if(l == r) return;
    int mid = (l + r) >> 1;

    creat(L(t), l, mid);
    creat(R(t), mid
    +1, r);
    }

    void updata(int t, int len)
    {
    if(node[t].l == node[t].r)
    {
    if(node[t].w < len)
    return;

    node[t].w
    -= len;
    ans
    = node[t].l;
    return;
    }

    if(len <= node[L(t)].w)
    updata(L(t), len);

    else
    updata(R(t), len);

    node[t].w
    = node[L(t)].w > node[R(t)].w ? node[L(t)].w : node[R(t)].w;
    }

    int main()
    {
    //freopen("data.in", "r", stdin);

    int h, n, i, b;
    while(~scanf("%d%d%d", &h, &w, &n))
    {
    if(h > n) h = n; //注意这里,如果h>n则n以后的数都更新不到,最大建树建到n就可以。
    creat(1, 1, h);
    for(i = 1; i <= n; i++)
    {
    scanf(
    "%d", &b);
    ans
    = 0;
    updata(
    1, b);
    printf(
    "%d\n", ans ? ans : -1);
    }
    }
    return 0;
    }

                       

  • 相关阅读:
    mysql 复合索引 为什么遵循最左原则
    php设计模式--门面模式
    php设计模式--装饰器模式
    php 设计模式 --组合器模式
    2020暑假训练日记
    2020省选联考翻车记
    题解 洛谷P6560 [SBCOI2020] 时光的流逝
    题解 洛谷P6562 [SBCOI2020] 归家之路
    题解 洛谷P6561 [SBCOI2020] 人
    题解 CF1372E Omkar and Last Floor
  • 原文地址:https://www.cnblogs.com/vongang/p/2178075.html
Copyright © 2020-2023  润新知