题意:给一个h*w的公告栏,另有n条广告,它们是一个1*wi的矩形,按照输入的顺序,从左到右,从上到下,贴在公告栏,问它能贴在第几行,如果不能,输出-1.
思路:线段树应用:每个结点l,r代表高度(h)区间,val代表这个区间最大宽度。
#include<cstdio>
#include<cstring>
#define Max(a,b) (a)>(b)?(a):(b)
using namespace std;
const int maxn = 2*(1e5+1);
struct segtree
{
int l,r;
int val;// 代表这个区间宽度的最大值
}segnode[4*maxn];
void build(int root,int start,int end,int w)
{
segnode[root].l=start;
segnode[root].r=end;
segnode[root].val=w;
if(start==end)return;
int mid=(start+end)/2;
build(2*root,start,mid,w);
build(2*root+1,mid+1,end,w);
}
void Update(int root,int w)
{
if(segnode[root].l==segnode[root].r)
{
if(segnode[root].val>=w)
{
segnode[root].val-=w;
printf("%d\n",segnode[root].l);
return;
}
}
if(w<=segnode[root*2].val)
Update(root*2,w);
else
Update(root*2+1,w);
segnode[root].val=Max(segnode[root*2].val,segnode[root*2+1].val);
}
int main()
{
int h,w,n;
//freopen("in.txt","r",stdin);
while(~scanf("%d%d%d",&h,&w,&n))
{
if(h>=n)h=n;
build(1,1,h,w);
for(int t=0;t<n;t++)
{
int wi;
scanf("%d",&wi);
if(wi>segnode[1].val)printf("-1\n");
else
Update(1,wi);
}
}
}