HDU 2795 Billboard 线段树

来源:互联网 发布:网络投资挣钱 编辑:程序博客网 时间:2024/06/14 06:56

题目:传送门


题意:

有一个巨大的矩形广告牌,高为h,宽为w。一开始广告牌是空的,之后广告会被一条一条的依次贴上去。每张广告都是高度为1宽度为wi的细长的矩形纸条。贴广告的人总是会优先选择最上面的位置来帖,而且在所有最上面的可能位中,他会选择最左面的位置,而且不能把已经贴好的广告盖住。如果没有合适的位置了,那么这张广告就不会被贴了(输出-1)。现在已知广告牌的尺寸和每张广告的尺寸,求每张广告被贴在的行编号。

思路:线段树,以行数建树,底层区间纪录每行所剩余的空间;

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<map>#include<stack>#include<queue>#include<algorithm>#include<set>#include<vector>#include<cmath>#define lmid l,m,rt<<1#define rmid m+1,r,rt<<1|1using namespace std;const int MAXN=200005;int tree[MAXN<<2];int h,w,n;void pushup(int rt){   tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);}void build(int l,int r,int rt){   if(l==r)   {      tree[rt]=w;      return ;   }   int m=(l+r)>>1;   build(lmid);   build(rmid);   pushup(rt);}int update(int C,int l,int r,int rt){   if(l==r)   {      tree[rt]-=C;      return l;   }   int m=(l+r)>>1;   int res;   if(tree[rt<<1]>=C) res=update(C,lmid);   else res=update(C,rmid);   pushup(rt);   return res;}int main(){   while(scanf("%d%d%d",&h,&w,&n)==3)   {      if(h>n)         h=n;      build(1,h,1);      for(int i=0;i<n;i++)      {         int a;         scanf("%d",&a);         if(tree[1]<a) cout<<"-1"<<endl;         else cout<<update(a,1,h,1)<<endl;      }   }   return 0;}


原创粉丝点击