

#include<iostream> using namespace std; #include<cstdio> #include<algorithm> #define maxn 200005 int h,n,w; int root[maxn<<4]; int ans;//标记 void make_tree(int l,int r,int rt) { if(l==r) { root[rt]=w; return ; } int mid=(r+l)/2; make_tree(l,mid,rt*2); make_tree(mid+1,r,rt*2+1); root[rt]=max(root[rt*2],root[rt*2+1]); } void query(int b,int l,int r,int rt) { if(root[rt]<b)return ; if(l==r) { root[rt]-=b; ans=l; return; } int mid=(l+r)/2; if(ans==-1) query(b,l,mid,rt*2); if(ans==-1) query(b,mid+1,r,rt*2+1); if(ans!=-1) root[rt]=max(root[rt*2],root[rt*2+1]); } int main() { while(scanf("%d%d%d",&h,&w,&n)!=EOF) { if(h>200000) h=200000; make_tree(1,h,1); while(n--) { int a; ans=-1; scanf("%d",&a); query(a,1,h,1); printf("%d\n",ans); } } return 0; }
第一眼又是坑长的英文,细看外加用了点灵格斯,题目大意是一个广告栏要加广告上去,输入广告栏的长(h)宽(w)和所加广告的个数n,然后n行依次输入n个数代表所加广告的宽(广告的长都是1),每一次加广告上去,都尽量把广告往左上位置放,每放一个广告输出它放在广告栏的第几行(长度),没有位置放则输出"-1"。
用线段树,建树,每一个root[rt]=w,放广告就从左树先查找,长度从小到大,当满足root[rt]>n[i]能放广告时,记下left位置,并相应的减去x[i],输出left;不能放输出"-1"。