题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=2795
线段树初学题目~~
思路比较简单,记录区间剩余容量的最大值~~~
每次询问的时候,只要当前区间范围内的最大值是否足够放入广告,不够的话,只能输出-1
够的话,那么就看一下左儿子区间的最大值是否足够放,是的话就往左儿子区间走~
否则往右儿子区间走~~
#include<iostream>
#include<cstdio>
#include<algorithm>
#define rr (v<<1|1)
#define ll (v<<1)
#define tmid ((l+r)>>1)
using namespace std;
int n,m,p;
int mx[800000];
void make_tree(){
for(int i=0;i<=n*4;mx[i++]=m);
}
int query(int val,int l,int r,int v){
if(mx[v]<val) return -1;
if(l==r) return l;
if(mx[ll]>=val)
return query(val,l,tmid,ll);
return query(val,tmid+1,r,rr);
}
int update(int x,int val,int l,int r,int v){
if(l==r) return mx[v]-=val;
int mxr,mxl;
if(x<=tmid)
mxl=update(x,val,l,tmid,ll),mxr=mx[rr];
else mxl=mx[ll],mxr=update(x,val,tmid+1,r,rr);
if(mxl>=mxr) mx[v]=mxl;
else mx[v]=mxr;
return mx[v];
}
int main(){
int i,j,op,tmp;
while(~scanf("%d%d%d",&n,&m,&p)){
n=n<p?n:p;
make_tree();
while(p--){
scanf("%d",&op);
tmp=query(op,1,n,1);
printf("%d\n",tmp);
if(tmp!=-1){
update(tmp,op,1,n,1);
}
}
}
return 0;
}