hdu 2975 Billboard

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=2795

解题思路:

题目大意: 

有一块h*w的矩形广告板,要往上面贴广告; 然后给n个1*wi的广告,要求把广告贴上去; 而且要求广告要尽量往上贴并且尽量靠左; 求

第n个广告的所在的位置,不能贴则为-1。
 
算法思想:

利用线段树可以求区间的最大值,将位置即h用来建树(h<=n,大了没有意义),树中存储的为该位置还拥有的空间,若左子树的最大值

大于他,就查询左子树,否则查询右子树。

AC代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

const int N = 200005;
struct node{
    int l,r;
    int num;
}tree[N<<2];
int h,w,n;

void build(int id,int l,int r){
    tree[id].l = l;
    tree[id].r = r;
    tree[id].num = w;
    if(l == r)
        return ;
    int mid = (l+r)>>1;
    build(id<<1,l,mid);
    build(id<<1|1,mid+1,r);
}

int query(int id,int len){
    if(tree[id].l == tree[id].r){
        tree[id].num -= len;
        return tree[id].l;
    }
    else{
        int sum1 = 0,sum2 = 0;
        if(len <= tree[id<<1].num)
            sum1 = query(id<<1,len);
        else if (len <= tree[id<<1|1].num)
            sum2 = query(id<<1|1,len);
        tree[id].num = max(tree[id<<1].num,tree[id<<1|1].num);
        return sum1+sum2;
    }
}

int main(){
    while(~scanf("%d%d%d",&h,&w,&n)){
        if(h > n)
            h = n;
        build(1,1,h);
        int x;
        for(int i = 1; i <= n; i++){
            scanf("%d",&x);
            if(tree[1].num >= x)
                printf("%d\n",query(1,x));
            else
                printf("-1\n");
        }
    }
    return 0;
}


你可能感兴趣的:(线段树)