题意:h*w的木板,放进一些1*L的物品,求每次放空间能容纳且最上边的位子
思路:每次找到最大值的位子,然后减去L
线段树功能:query:区间求最大值的位子(直接把update的操作在query里做了)
题意:有一块长方形h*w的广告板,往上面贴广告,然后给n个1*wi的广告,要求把广告贴上去,如果前面的行可以贴,就要贴前面的并且要靠左贴,前面的贴不下就贴在下面,
广告的高度是wi,如果能贴在上面输出最小的高度,如果不能就输出-1。
解题思路:如果以行数为区间,建立线段树,他给的h有10^9次,是创不了10^9这么大的数组的。然而我们知道给定N个广告,应为宽度一定,那么最高也不会超过N;所以我们就建 n个节点的线段树 而n<=20W
样例:
Sample Input
3 5 5 2 4 3 3 3
Sample Output
1 2 1 3 -1
#include <cstdio> #define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 const int maxn = 200005; int h,w,n; struct Tree{ int value; }tree[maxn<<2]; int max(int va,int vb){ return va>vb?va:vb; } void PushUP(int rt) { tree[rt].value = max( tree[rt<<1].value, tree[rt<<1|1].value ); } void build(int l,int r,int rt) { tree[rt].value=w; //初始化 if (l == r) { return ; } int m = (l + r) >> 1; build(lson); build(rson); //PushUP(rt); 这题初始化w 没必要这步了 } /* void update(int x,int p,int l,int r,int rt) {//p表示要进行操作的人是第几个 if (l == r) { tree[rt].value -=x; return ; } int m = (l + r) >> 1; if (p <= m) update(x , p , lson); else update(x , p , rson); PushUP(rt); //这步需要, } */ int query(int x,int l,int r,int rt) { if (l == r) { //update(x,r,1,h,1); tree[rt].value -= x; return r; } int m = (l + r) >> 1; int ret = 0 ; if (x <= tree[rt<<1].value) ret= query(x , lson); //先取左 else ret= query(x , rson); PushUP(rt); //往上更新 return ret; } int main() { while (~scanf("%d%d%d",&h,&w,&n)) { if (h > n) h = n; //比较重要的一步 build(1 , h , 1); while (n --) { int x; scanf("%d",&x); if (tree[1].value<x) printf("-1 "); else printf("%d ",query(x , 1 , h , 1)); } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。