/*
这道题目如果你想通了,知道可以用线段树的话,那么这是一道简单的线段树题目,我比赛的时候没有想出来,
赛后做时,看了别人的代码,才明白过来,就是以广告牌的长度建树,当为叶子节点时,它的值为广告牌的宽度,
后然不断的询问,如果真正理解了线段树的意义的话,就可以马上知道该题是用线段树,我只是菜鸟,不过这道题目
还有几个细节要注意一下,不然也过不了,下面我会注释出来!
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
const int maxn=200005;
using namespace std;
int h,w,n;
int a[4*maxn];
void build(int u,int l,int r)//建树
{
if(l==r)//叶子节点
{ a[u]=w;
return ;
}
int mid=(l+r)>>1;
build(2*u,l,mid);
build(2*u+1,mid+1,r);
a[u]=max(a[2*u],a[2*u+1]);//更新节点的值
}
int query(int u,int l,int r,int pos)
{
if(l==r)
{
a[u]-=pos;
return l;
}
int mid=(l+r)>>1;
int sum;
if(a[2*u]>=pos)sum=query(2*u,l,mid,pos);
else sum=query(2*u+1,mid+1,r,pos);
a[u]=max(a[2*u],a[2*u+1]);
return sum;
}
int main()
{
int i;
while(scanf("%d%d%d",&h,&w,&n)!=EOF)
{
if(h>n)h=n;//这里要特别注意,当h>n时,其实我们可以以n建树,这样就不必要建树这么大,不然就会爆掉,出现Runtime Error(ACCESS_VIOLATION)
build(1,1,h);
for(i=1; i<=n; i++)
{
int x,y;
scanf("%d",&x);
if(a[1]<x)printf("-1\n");
else
{
y=query(1,1,h,x);
printf("%d\n",y);
}
}
}
return 0;
}
hdu 2795
最新推荐文章于 2015-12-14 20:25:36 发布