给出一个广告牌大小,给出n个广告的长度,每个广告高度占一行,按照顺序尽量安排广告在靠左上角位置
问,每次给出一个广告长度,求出在哪一行?
很难想到线段树啊。。。。把行数给建树了,val维护当前区间的行内某行最大的空位数,然后安排的时候,优先左树去用
有点类似二分了。。。。
#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <algorithm> #define MID(x,y) ( ( x + y ) >> 1 ) #define L(x) ( x << 1 ) #define R(x) ( x << 1 | 1 ) using namespace std; const int MAX = 200010; struct Tnode{ int l,r,val;}; Tnode node[MAX<<2]; void init() { memset(node,0,sizeof(node)); } void build(int t,int l,int r,int w)//val存放当前最大的空位值 { node[t].l = l; node[t].r = r; node[t].val = 0; if( node[t].l == node[t].r - 1 ) { node[t].val=w ; return; } int mid = MID(l,r); build(L(t),l,mid,w); build(R(t),mid,r,w); node[t].val=max(node[L(t)].val,node[R(t)].val); } int update(int t,int wh) { int ans; if(node[t].val<wh)return -1; if( node[t].l == node[t].r - 1 && node[t].val >= wh) { node[t].val -= wh; return node[t].l; } if(wh<=node[L(t)].val) ans=update(L(t),wh); else if(wh<=node[R(t)].val) ans= update(R(t),wh); node[t].val=max(node[L(t)].val,node[R(t)].val); return ans; } int main() { int h,w,n,wh,ans; while(~scanf("%d%d%d",&h,&w,&n)) { init(); build(1,1,min(h,n)+1,w); //printf("%d\n",node[1].val); for(int i=0;i<n;i++) { scanf("%d",&wh); ans=update(1,wh); //if(ans>h)ans=-1; printf("%d\n",ans); } } }