HDU 2759 Billboard 线段树


  
  
  
  
Billboard
Time Limit:8000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Submit  Status  Practice  HDU 2795

Description

在学校的入口处有一个巨大的矩形广告牌,高为h,宽为w。所有种类的广告都可以贴,比如ACM的广告啊,还有餐厅新出了哪些好吃的,等等。。
 
在9月1号这天,广告牌是空的,之后广告会被一条一条的依次贴上去。
 
每张广告都是高度为1宽度为wi的细长的矩形纸条。
 
贴广告的人总是会优先选择最上面的位置来帖,而且在所有最上面的可能位置中,他会选择最左面的位置,而且不能把已经贴好的广告盖住。
如果没有合适的位置了,那么这张广告就不会被贴了。
 
现在已知广告牌的尺寸和每张广告的尺寸,求每张广告被贴在的行编号。

Input

多组样例,不超过40个。
 
对每组样例,第一行包含3个整数h,w,n(1 <= h,w <= 10^9; 1 <= n <= 200,000) -广告牌的尺寸和广告的个数。  下面n行每行一个整数 wi (1 <= wi <= 10^9) -  第i张广告的宽度.

Output

对每张广告,输出它被贴在的行编号(是1到h之间的数),顶部是第一行。如果某广告不能被贴上,则输出-1。

Sample Input

	
		3 5 5
2
4
3
3
3 

Sample Output

	
		1
2
1
3
-1 





#include<stdio.h>
#include<string.h>
int max(int x,int y)
{
	if(x>y) return x;
	else return y;
}
struct s
{
	int right,left,ma,c;
}st[800000];
int h,w,n,i,t,s,count ;
void build(int id,int l,int r)
{
	st[id].left =l;
	st[id].right =r;
	if(l==r)
	{
		st[id].ma =w;
		st[id].c =++count;
	 } 
	else
	 {
		int mid=(l+r)/2;
		build(2*id,l,mid);
		build(2*id+1,mid+1,r);
		st[id].ma =w;
	}
	
}
int  gengxing(int id,int x,int l,int r )
{
	int t;
	if(st[id].ma <x) return -1;
	if(l==r) 
	{
		st[id].ma =st[id].ma -x;
		return st[id].c ;
	}
	if(x<=st[2*id].ma ) 
	{
		t= gengxing(2*id,x,st[2*id].left ,st[2*id].right);
	}
	else {
		t= gengxing(2*id+1,x,st[2*id+1].left,st[2*id+1].right);
	}
	st[id].ma =max(st[2*id+1].ma ,st[2*id].ma);
	return t;
}

int main()
{
	//freopen("in.txt","r",stdin);
	
	while(scanf("%d%d%d",&h,&w,&n)!=EOF)
	{
		if(n>h)//建树的时候需要稍微判断一下

		{	s=h;
			build(1,1,h);
		}
		else {
			build(1,1,n);
			s=n;
		}
		count =0;
		for(i=0;i<n;i++)
		{
			scanf("%d",&t);
			printf("%d\n",gengxing(1,t,1,n));
		}
 	} 
}

你可能感兴趣的:(HDU 2759 Billboard 线段树)