数据结构 线段树 HDU 2795Billboard(单点更新)

本文介绍了一种使用线段树数据结构解决特定广告牌布局问题的方法。该问题涉及在一个给定尺寸的广告牌上放置一系列宽度为1的广告条,每次放置都是横向进行且长度不一。通过构建线段树并实现单点更新和查询最大剩余空间的功能,能够有效地确定每个广告条在广告牌上的放置位置。

题意:有h*w的 广告板子,现在要添加n次,的广告,每个广告宽度都为1,而且都只能横着放,依次输入每个广告的长度 x,问广告插入在哪一行,插不了输出-1

解法:线段树 ,单点更新,找还剩下的地方的最大值,update就直接在 query里进行了



#include <stdio.h>
#include <string.h>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int N=222222;
//一开始想不明白肯定会爆
//n次放入可以放在重复层,而且 n 一定是小于等于h的 
//再长的h也是浪费,所以最大用2X10^5,不用10^9
int Max[N<<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;	
	if(l==r) return ;
	int m=(l+r)>>1;
	build(l,m,rt<<1);
	build(m+1,r,rt<<1|1);
}
int query(int x,int l,int r,int rt){
	//x 新的一行 
	if(l==r){
		Max[rt]-=x;
		return l;//返回这一行 
	}
	int m=(l + r)>>1;
	int ret=0;
	// 如果 左边比 x大,往左走 
	if(Max[rt<<1]>= x)
		ret=query(x,l,m,rt<<1);
	else ret=query(x,m+1,r,rt<<1|1);
	PushUP(rt);
	return ret;
}
int main()
{
	while(~scanf("%d%d%d",&h,&w,&n))
	{
		// n 为添加的长度,h为行数
		// n一定是小于等于h的可以减少很多没用的行数 
		if(h>n) h=n;
		build(1,h,1);
		while(n--)
		{
			int x;
			scanf("%d",&x);
			// Max[1] 最大的一行的长度 
			if(Max[1]<x) printf("-1\n");
			else printf("%d\n",query(x,1,h,1));
		}
	}
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值