gfoj 告示板

题目:http://www.gdfzoj.com/oj/contest/143/problems/5

李华是一名品学兼优、积极向上、热爱国家、热爱人民的优秀高中生。作为一名学生干部,他负责管理学生会的告示板。

告示板大小为h行,w列,各个学生社团有时会将高为1,长为L的告示贴到告示板上。当有人张贴告示时,李华会把告示张贴在空间足够的最高那一行的尽可能靠左的位置;如果空间不够,这张告示将不会被张贴。

给你告示板和各张告示的大小,请你帮助李华找到每张告示应张贴在哪一行

对于30%数据 n<=2000 数据组数<=40

对于60%数据 n<=20000 数据组数<=10

对于100%数据 n<=200000 数据组数 <=2

h,w<=10e9
 

 

一开始以为按h线段树,但10^9吓到我了。。。离散化居然不行。后来发现只用线段树 min(n,h) 即可,因为告示板不可能贴到大于n的行数。。。(看似有毒)

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

struct node
{
	int l,r,rest;//
};

const int maxS=200000;
int h,w,n;
node M[4*maxS+5];

void pushup(int x)
{
	M[x].rest=max(M[2*x].rest,M[2*x+1].rest);
}

void build(int x,int l,int r)
{
	int mid=(l+r)/2;
	
	M[x].l=l;	M[x].r=r;	M[x].rest=w;
	if (l==r)
		return ;
	build(2*x,l,mid);
	build(2*x+1,mid+1,r);
}

void update(int x,int len)
{
	int mid=(M[x].l+M[x].r)/2;
	
	if (M[x].l==M[x].r)
	{
		M[x].rest-=len;
		printf("%d\n",M[x].l);
		return ;
	}
	if (M[2*x].rest>=len)
		update(2*x,len);
	else if (M[2*x+1].rest>=len)
		update(2*x+1,len);
	else
	{
		printf("%d\n",-1);
//		return ;
	}
	pushup(x);
}

int main()
{
	int i,L;
	
	freopen("a.txt","r",stdin);
	freopen("b.txt","w",stdout);
	while (scanf("%d%d%d",&h,&w,&n)!=EOF)
	{
		build(1,1,min(n,h));
		for (i=1;i<=n;i++)
		{
			scanf("%d",&L);
			update(1,L);
		}
	}
	
	
	
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值