HDOJ 2795 ----线段树(区域覆盖问题)

本文介绍了一种利用线段树实现的广告牌最优广告粘贴位置查询算法,通过动态更新和查询操作,解决广告宽度与广告牌大小匹配的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:有一块K*W的广告牌,寻找1*L的广告的最大粘贴位置。

算法思想:

主要使用线段树的,查询和更新操作。初始时建立一个有h个叶子节点的线段树,每个节点的之都为W,然后进行查询操做,查询每个广告的宽度是否满足Max[1],不满足是输出-1,满足时是输出最优行号,每次查询是伴随着要对线段树进行动态更新。下面的代码中将查询操作和更新操作写在一起了。

代码如下:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN=222222;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int Max[MAXN<<2];
int h,w,n;
void PushUp(int rt){
    Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);//根节点记录最大宽度
}
void Build(int l,int r,int rt){
   Max[rt]=w;//初始时每个叶子节点的宽度为w,共有h个叶子节点
   if(l==r)
       return ;
   int m=(l+r)>>1;
   Build(lson);
   Build(rson);
}

int Query(int x,int l,int r,int rt){
    if(l==r){//当查询到叶子节点时更新最大宽度
        Max[rt]-=x;
        return l;//返回此叶子所代表的行号
    }
    int m=(l+r)>>1;
    int ret=(Max[rt<<1]>=x)? Query(x,lson):Query(x,rson);//寻找最大的查询结果
    PushUp(rt);//更新线段树
    return ret;
}

int main(){
    while(cin>>h>>w>>n){
        if(h>n) h=n;//此步为了减少线段树的开销
        Build(1,h,1);
        while(n--){
            int x;
            cin>>x;      
            if(Max[1]<x)cout<<-1<<endl;
            else
                cout<<Query(x,1,h,1)<<endl;      
        }    
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值