题意:h*w的木板,放进一些1*L的物品,求每次放空间能容纳且最上边的位子
思路:我们从左向右看,剩余的空间当做一个权值,则有h个权值。由于只有n个消息,所以最坏情况是每条消息占一行,最大n行。
每次判断上边的能不能放,能则放上边,不能则放下边。
线段树功能:query:区间求最大值的位子(直接把update的操作在query里做了)

1 #include<iostream> 2 #include<string> 3 #include<queue> 4 #include<map> 5 #include<stack> 6 #include<cmath> 7 #include<functional> 8 #include<algorithm> 9 using namespace std; 10 #define lson l , m , rt << 1 11 #define rson m + 1 , r , rt << 1 | 1 12 const int maxn = 320000; 13 int sum[maxn<<2]; 14 int n,h,w; 15 16 int operate(int a,int b){ 17 return max(a,b); 18 } 19 20 21 void PushUp(int rt){ 22 sum[rt]=operate(sum[rt<<1],sum[rt<<1|1]); 23 } 24 25 void bulid(int l=1,int r=h,int rt=1){ 26 if(l==r){ 27 sum[rt]=w; 28 return ; 29 } 30 int m=(l+r)>>1; 31 bulid(lson); 32 bulid(rson); 33 PushUp(rt); 34 } 35 36 int query(int x,int l=1,int r=h,int rt=1){ 37 if(l==r){ 38 sum[rt]-=x; 39 return l; 40 } 41 int m = (l + r) >> 1;; 42 int ans=0; 43 if(x<=sum[rt<<1])ans=query(x,lson); 44 else ans=query(x,rson); 45 PushUp(rt); 46 return ans; 47 } 48 49 50 int main(){ 51 52 int tmp; 53 while(~scanf("%d%d%d",&h,&w,&n)){ 54 55 if(h>n)h=n; 56 bulid(); 57 while(n--){ 58 scanf("%d",&tmp); 59 if(tmp>sum[1])puts("-1"); 60 else printf("%d\n",query(tmp)); 61 } 62 63 } 64 65 return 0; 66 }