这是一道线段树的单点更新的问题。题目的意思是有一块板子,长宽分别为W,H,然后有n块1*w海报
让你把这n快海报贴在这块板子上,尽量往板子的上方贴,同一行尽量往板子的左边贴。
对于第i块海报如果能够贴下则输出能贴在第几行,否则输出-1。
#include<stdio.h>
#define maxn 200005
int 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;
}