题目链接:
HDU 2795 Billboard
题意:
有个高为h宽为w的墙用于贴宣传海报,每张海报高为1,宽为wi,每张海报在能张贴的情况下优先选择最上面的最左面;
共有n张海报,问贴每张海报所在的行,如果贴不下,就输出-1.
分析;
建立区间为[1,h]的线段树,叶子结点即表示相应层。线段树中存储当前所有层中的最大剩余长度,
查询和更新操作其实放在一起了。
玩玩没想到的是,题目中说了1<=h<=1e9,然而非要自己在读入时限制一下h,要不然会RE,o(╯□╰)o
//7384K 2589MS
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
using namespace std;
#define lson(x) (x<<1)
#define rson(x) ((x<<1)|1)
const int maxn=200010;
struct SegTree{
int left,right,len;
}segtree[maxn<<3];
void build(int width,int left,int right,int cur)
{
segtree[cur].left=left;
segtree[cur].right=right;
segtree[cur].len=width;
if(left==right) return ;
int mid=(left+right)>>1;
build(width,left,mid,lson(cur));
build(width,mid+1,right,rson(cur));
}
int query(int width,int cur)
{
int len=segtree[cur].len;
int left=segtree[cur].left;
int right=segtree[cur].right;
if(len<width) return -1;
if(left==right) {
segtree[cur].len=len-width;
return left;
}
int tmp;
if(segtree[lson(cur)].len>=width) tmp=query(width,lson(cur));
else tmp=query(width,rson(cur));
segtree[cur].len=max(segtree[lson(cur)].len,segtree[rson(cur)].len);
return tmp;
}
int main()
{
//freopen("hdu2795in.txt","r",stdin);
int h,w,n,d,T=40;
while(~scanf("%d%d%d",&h,&w,&n)){
if(h>200000) h=200000;//尼玛,得自己限制h,要不然RE,完全搞不懂。。。
build(w,1,h,1);
for(int i=0;i<n;i++){
scanf("%d",&d);
printf("%d\n",query(d,1));
}
}
return 0;
}