這個題一開始有點傻,用的求和的線段樹,多了很多無用的查找步驟,然後超時,然後優化了好久纔想起來用區間最大值可以避免很多無用查找層次,然後重寫。
經過不斷的改寫,重寫,初步掌握線段樹的靈活飄逸的代碼風格。
code:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=200100;
int sumtree[maxn<<2];
void pushUp(int rt)
{
sumtree[rt]=max(sumtree[rt<<1],sumtree[rt<<1|1]);
}
void build(int w,int l,int r,int rt)
{
if(l==r)
{
sumtree[rt]=w;
return ;
}
int m=(l+r)/2;
build(w,lson);
build(w,rson);
pushUp(rt);
}
void updateandQuery(int w,int l,int r,int rt)
{
//printf("l=%d-------r=%d\n",l,r);
if(l==r&&sumtree[rt]>=w)
{
sumtree[rt]-=w;
printf("%d\n",l);
return;
}
int m=(l+r)/2;
if(w<=sumtree[rt<<1])
{
updateandQuery(w,lson);
}
else if(w<=sumtree[rt<<1|1])
{
updateandQuery(w,rson);
}
pushUp(rt);
//printf("sum[%d]=%d",rt,sumtree[rt]);
}
int main()
{
int h,w,n,x;
while(scanf("%d%d%d",&h,&w,&n)!=EOF)
{
int na=min(n,h);
memset(sumtree,0,sizeof(sumtree));
build(w,1,na,1);
for(int i=0;i<n;i++)
{
scanf("%d",&x);
if(x>sumtree[1])
printf("-1\n");
else
updateandQuery(x,1,na,1);
}
}
return 0;
}