HDU 2795 Billboard

本文介绍了一种使用线段树进行单点更新并查询区间最大值的问题解决方法。通过构建线段树来维护一系列叶子节点的值,并在接收到更新请求时,能够有效地更新特定节点并返回该节点的位置。此方法适用于处理区间查询和更新操作。


思路: 我们可以将每一行当成一个叶子节点,起初叶子节点的均为w,此时我们便将问题转化为维护区间区间最大值即可,想通了之后便是一道简单的线段树单点更新的题目~~~


#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 222222;
int max_item[MAXN<<2];
int h, w, n, id;

inline int min(int a, int b)
{
    return a < b ? a : b;
}

inline int max(int a, int b)
{
    return a > b ? a : b;
}

void Push_Up(int rt)
{
    max_item[rt] = max(max_item[rt<<1], max_item[rt<<1|1]);
}

void bulid(int l, int r, int rt)
{
    if(l == r)
    {
        max_item[rt] = w;
        return;
    }
    int m = (l + r)>>1;
    bulid(l, m, rt<<1);
    bulid(m + 1, r, rt<<1|1);
    Push_Up(rt);
    return ;
}

void update(int val, int l, int r, int rt)
{
    if(l == r)
    {
        max_item[rt] -= val;
        id = l;
        return ;
    }
    int m = (l + r)>>1;
    if(max_item[rt<<1] >= val)
        update(val, l, m, rt<<1);
    else
        update(val, m + 1, r, rt<<1|1);
    Push_Up(rt);
    return ;
}

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

    int t, t_w;

    while(scanf("%d %d %d", &h, &w, &n) != EOF)
    {
        t = min(h, n);
        bulid(1, t, 1);
        for(int i = 1; i <= n; ++i)
        {
            scanf("%d", &t_w);
            if(max_item[1] < t_w)
                printf("-1\n");
            else
            {
                update(t_w, 1, t, 1);
                printf("%d\n", id);
            }
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值