题意:
有一个广告牌,长是h宽为w。现在要在上面贴纸条做广告,每个纸条都是单位长度h=1,但是w宽不一致,要求尽可能的往顶头贴,再尽可能的往左边贴,求给出给定的纸条能贴在广告牌的第几行
分析:
每一行看作一个点,父节点记录最大还能插入的纸条
//AC CODE:
#include<iostream> #include<cmath> #include<algorithm> #include<vector> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> using namespace std; #define Max(a,b) a>b?a:b #define Min(a,b) a<b?a:b #define _clr(str,val) memset(str,val,sizeof(str)) const int maxn = 222222; int h , w , n; int nowMax[maxn<<2]; void PushUP(int rt) { nowMax[rt] = Max(nowMax[rt<<1] , nowMax[rt<<1|1]); } void build(int l,int r,int rt) { nowMax[rt] = w; if (l == r) return ; int m = (l + r) >> 1; build(l , m , rt << 1); build(m + 1 , r , rt << 1 | 1); } int query(int x,int l,int r,int rt) { if (l == r) { nowMax[rt] -= x; return l; } int m = (l + r) >> 1; int ret = (nowMax[rt<<1] >= x) ? query(x , l , m , rt << 1) : query(x , m + 1 , r , rt << 1 | 1); PushUP(rt); return ret; } int main() { while (scanf("%d%d%d",&h,&w,&n)!=EOF) { if (h > n) h = n; build(1 , h , 1); while (n --) { int x; scanf("%d",&x); if (nowMax[1] < x) printf("-1\n"); else printf("%d\n",query(x , 1 , h , 1)); } } return 0; }