HDU 2795 线段树

题意:给你一个长方形的木板,往上面贴广告,广告的要求是如果第一行可以贴下那么就贴在第一行,而且尽可能的往左贴,最后输出这个广告贴在哪一行。给你高度h,宽度w的长方形木板和n个操作,下面有n行操作,每一行有一个数表示广告的宽度,所有广告的高度都是1.如果木板可以容纳这个广告就输出贴在哪行,如果不能就输出-1。

思路:因为之前别人介绍这道题的时候说这是道坑题,所以先百度看了一下坑的所在,这题的数据看起来很大,10的9次方,但是其实我们只要按照他的高度建树就可以了,坑就在这个地方,如果按照宽度建树,肯定会爆掉,因为他最多有n个广告,所以高度最大就是n=200000;那么我们只要按照这个来建树就简单的很多了,想到这里那么这题也就是一道水题了。只要建树的时候看一下到底是h还是n大,谁小就按照谁建树就OK了,虽然思路看过了,但是自己写的时候建树的时候逻辑没处理好,非法内存访问了几次,还是太弱了,QAQ。

#include <stdio.h>
#include <algorithm>
using namespace std;

#define MAX 220000

int value[4*MAX];//这个数组表示当前节点我还有多少空间可用 

void build(int l,int r,int id,int val)
{
	value[id]=val;
	if(l==r)return ;
	int mid=l+r>>1;
	build(l,mid,id<<1,val);
	build(mid+1,r,id<<1|1,val);
}

void updata(int l,int r,int id,int val)
{
	if(l==r)
	{
		value[id]-=val;
		printf("%d\n",l);
		return ;
	}
	int mid=l+r>>1;
	if(val<=value[id<<1])updata(l,mid,id<<1,val);
	else updata(mid+1,r,id<<1|1,val);
	value[id]=max(value[id<<1],value[id<<1|1]);//更新当前节点 
}

int main()
{
	int h,w,n,t;
	while(scanf("%d %d %d",&h,&w,&n)!=EOF)
	{
		if(h>MAX)
		h=MAX;
		build(1,h,1,w);//建树 
		while(n--)
		{	 
			scanf("%d",&t);
			if(t>value[1])
			{
				printf("-1\n");
				continue;
			}
			updata(1,h,1,t);
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值