码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 2795 Billboard (线段树单点更新)

时间:2014-06-28 08:13:53      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:style   blog   2014   os   name   for   



题意:h,w,n:有一个h*w尺寸的木板,n张1*wi的海报,贴海报的位置尽量高,尽量往左,问每张海报贴的高度


看到1 <= h,w <= 10^9; 1 <= n <= 200,000,应该就是线段树了。


关键在怎么建树,这里我们对h进行分割,每个高度都有等长的w,我们从上往下贴,如果当前高度

(在同一高度上l==r)的长度可以满足wi则可以贴,否则继续往下寻找。


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define M 303
#define inf 0x3fffffff
#define maxn 500000*2

struct Tree
{
	int left,right,num;
}tree[maxn];
int s,h,w,n;
void build_tree(int l,int r,int id)
{
	tree[id].left=l;tree[id].right=r;tree[id].num=w;
	if(l!=r)
	{
		int mid=(l+r)/2;
		build_tree(l,mid,id*2);
		build_tree(mid+1,r,id*2+1);
	}
}
int query(int h,int id)
{
	int l=tree[id].left,r=tree[id].right;
	if(tree[id].right==tree[id].left)//在一个高度上
	{
		tree[id].num-=h;
		return tree[id].left;
	}
	else 
	{
		int pos;
		if(tree[id*2].num>=h) pos=query(h,id*2);
		else pos=query(h,id*2+1);
		tree[id].num=max(tree[id*2].num,tree[id*2+1].num);
		return pos;
	}
}
int main()
{
	while(~scanf("%d%d%d",&h,&w,&n))
	{
		build_tree(1,min(h,200000),1);
		int a;
		for(int i=0;i<n;i++)
		{
			scanf("%d",&a);
			if(tree[1].num<a) printf("-1\n");
			else printf("%d\n",query(a,1));
		}
	}
	return 0;
}


HDU 2795 Billboard (线段树单点更新),布布扣,bubuko.com

HDU 2795 Billboard (线段树单点更新)

标签:style   blog   2014   os   name   for   

原文地址:http://blog.csdn.net/u012861385/article/details/35277079

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!