您的位置:首页 > 其它

【hdu 2795】Billboard 线段树

2016-07-28 08:34 351 查看
好吧,老实说,如果不是小明提醒,我还真不一定想的倒是线段树,更有可能想到贪心,因为正确性是可以保证的,但是时间复杂度就不好说了,而此题也是一道不错的线段树吧,因为模型不是太裸,把宽度作为点的值,维护这个区间就好了,然后点维护的就是最大值,每次区间修改的时候只用优先修改最右边的值,而且数据范围也不用1e9那么大,实际上只用最多n个点

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ls u<<1,l,mid
#define rs u<<1|1,mid+1,r
using namespace std;
int h,w,n;

struct node{
int l,r,Max;
void init(){
l=r=0;
Max=0;
}
}nod[ 800020*4];

void push_up(int u){
nod[u].Max=max(nod[u<<1].Max ,nod[u<<1|1].Max );
}

void build(int u,int l,int r,int x){
nod[u].init() ;
nod[u].l =l,nod[u].r=r;
if(l==r){
nod[u].Max=x;
return;
}

int mid=(l+r)>>1;

build(ls,x);
build(rs,x);
push_up(u);
}

int update(int u,int l,int r,int add){
if(nod[u].Max <add)return -1;
if(l==r){
nod[u].Max-=add;
return l;
}

int mid=(l+r)>>1;
int ll=u<<1,rr=u<<1|1;

int ans;
if(nod[ll].Max>=add) ans = update(ls,add);
else ans=update(rs,add);

push_up(u);
return ans;
}

int main(){
while(scanf("%d%d%d",&h,&w,&n)!=EOF){
build(1,1,min(n,h),w);
int x;
for(int i=1;i<=n;i++){
scanf("%d",&x);
printf("%d\n",update(1,1,min(h,n),x));
//printf("\n");
}
}
return 0;
}/*
3 5 5
2
4
3
3
3
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: