hdu 2795(Billboard) 广告牌

来源:互联网 发布:日历js脚本 编辑:程序博客网 时间:2024/06/09 22:57

这是一道线段树的单点更新的问题。题目的意思是有一块板子,长宽分别为W,H,然后有n块1*w海报让你把这n快海报贴在这块板子上,尽量往板子的上方贴,同一行尽量往板子的左边贴。对于第i块海报如果能够贴下则输出能贴在第几行,否则输出-1。

#include<stdio.h>#define maxn 200005int w,num,h;struct Node{int l,r;int max;}tree[maxn*4];int max(int a, int b){return a>b?a:b;}void build(int l, int r, int rt){tree[rt].l=l;tree[rt].r=r;tree[rt].max=w;if(l==r)   return;int mid = (l+r)/2;build(l,mid,rt*2);build(mid+1,r,rt*2+1);}void update(int id, int rt){if(tree[rt].l==id&&tree[rt].r==id){tree[rt].max-=num;return ;}int mid=(tree[rt].l+tree[rt].r)/2;if(id<=mid){update(id,rt*2);}if(id>mid){update(id,rt*2+1);}tree[rt].max=max(tree[rt*2].max,tree[rt*2+1].max);}int query(int l, int r, int rt){if(tree[rt].max<num)   return -1;if(tree[rt].l==tree[rt].r) return l; int mid=(tree[rt].l+tree[rt].r)/2; if(tree[rt*2].max>=num) return query(l,mid,rt*2); else  return query(mid+1,r,rt*2+1);}int main(){int m;while(scanf("%d%d%d",&h,&w,&m)!=EOF){m>=h?build(1,h,1):build(1,m,1);while(m--){scanf("%d",&num);int ans = query(1,h,1);if(ans==-1) printf("-1\n");else{printf("%d\n",ans);update(ans,1);}}}return 0;}


 

0 0
原创粉丝点击