习题:公告板

题目:公告板
思路:

将公告板的高度看做一个区间,区间每个点的长度为wi。
构建维护区间最长长度的线段树,进行求解。
优先从上到下贴,即优先从最左侧区间开始黏贴。

※注意!要看是什么在决定区间长度的最大值,而这道题是n,不是h!

代码:
#include<bits/stdc++.h>
using namespace std;
const int MAX_N = 200050;
int c[4*MAX_N] = {0};

void up(int p)
{
    c[p] = max(c[2*p],c[2*p+1]);
}

int modify(int p,int l,int r,int v)
{
    if(l==r){
        c[p]-=v;
        return l;
    }
    if(c[p]<v){
        return -1;
    }
    int mid = (l+r)/2;
    int res = 0;
    if(c[2*p]>=v){
        res = modify(2*p,l,mid,v);
    }
    else if(c[2*p+1]>=v){///这里一定是else if,这有前后优先级,优先放前
        res = modify(2*p+1,mid+1,r,v);
    }

    up(p);
    return res; ///整个函数最重要的是返回值,在递归最外(结果递归)的res代表的就是函数的返回值
}

int main()
{
    int h,w,n;
    scanf("%d%d%d",&h,&w,&n);
    for(int i=0;i<4*MAX_N;i++){     ///先将区间的最大值全部设为w,因为初始值即为w,最大值也为w
        c[i] = w;
    }
    for(int i=0;i<n;i++){
        int length;
        scanf("%d",&length);
        if(length>w) {printf("-1");continue;}
        printf("%d\n",modify(1,1,h,length));      ///可以简单地理解,在修改的时候已经完成信息的输出了,那这时候就不需要查询了
        ///故没有query函数。这时候modify的返回类型是int
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值