#include<iostream>using namespace std;#include<cstdio>#include<algorithm>#define maxn 200005int 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"。