HDU 2795Billboard

题意:(刚开始没看懂题啊  很僵硬  )大概意思就是给你一个n*m的海报 然后  让你贴小广告,优先往上和往右,很明显要建树,这里对于数的叶子节点要分类考虑,首先n与K的关系,n<k时建树的叶子节点应该n,反之为k,存入数的是当前存在的位置最多多少,然后遍历树,若左节点的空位大于要求的调用左儿子,反之右儿子,若不存在直接输出-1即可;

#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<cstring>
#include<cstdio>
#define N 200010
#define INF 0x3f3f3f3f
using namespace std;
typedef struct node{
	int x;int y;int date;
}node;
node a[N*4];
int b[N];
void built(int root,int first,int end,int e){
	if(first==end){
		a[root].x=first;a[root].y=end;a[root].date=e;
		return ;
	}
	int mid=(first+end)/2;
	built(root*2,first,mid,e);
	built(root*2+1,mid+1,end,e);
	a[root].x=a[root*2].x;a[root].y=a[root*2+1].y;a[root].date=max(a[root*2].date,a[root*2+1].date);
}
void U(int root,int first,int end,int e,int p){
	if(first==end){
		if(a[root].date<p){
			b[e]=-1;
		}
		else{
			b[e]=first;
			a[root].date-=p;
		}
		return ;
	}
	int mid=(first+end)/2;
	if(a[root*2].date>=p)  U(root*2,first,mid,e,p);
	else U(root*2+1,mid+1,end,e,p);
	a[root].date=max(a[root*2+1].date,a[root*2].date);
}
int main(){
	int m,n,k;
	while(scanf("%d %d %d",&m,&n,&k)==3){
		int l;
		memset(b,0,sizeof(0));
		int p;
		if(m>=k){
			p=k;
		}
		else{
			p=m;
		}
		built(1,1,p,n);
		for(int i=1;i<=k;i++){
			scanf("%d",&l);
			U(1,1,p,i,l);
		}
		for(int i=1;i<=k;i++){
			printf("%d\n",b[i]);
		}
	}
	return 0;
}


posted @ 2017-10-03 20:25  wang9897  阅读(76)  评论(0编辑  收藏  举报