hdu 2795 Billboard(单点更新,区间查询)

题意:

h*w的白板。

有n个广告牌,每个广告牌是1*wi。必须放置在白板的upmost中的leftmost。

输出n个广告牌放置在第几行。如果放不下,输出-1。

 

数据规格:

h, w, and n (1 <= h,w <= 10^9; 1 <= n <= 200,000)

 

思路:

每行最少放一个,所以最多需要n行。

这道题要早最靠左的放得下广告牌的行号。线段树,,

 

代码:

const int maxn = 200005;
int maxs[maxn<<2];

int h,w,n;


void PushUp(int rt){
    maxs[rt] = max( maxs[rt<<1], maxs[rt<<1|1] );
}

void build(int l,int r,int rt){
    maxs[rt] = w;
    if(l == r) return;
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
}

int query(int x,int l,int r,int rt){

    if(l == r){
        maxs[rt] -= x;
        return l;
    }
    int m = (l + r) >> 1;
    int ret;
    if( maxs[rt<<1] >=x )
        ret = query(x,lson);
    else
        ret = query(x,rson);
    PushUp(rt);

    return ret;
}




int main(){

    while(scanf("%d%d%d",&h,&w,&n)!=EOF){
        h = min(h,n);
        build(1,h,1);

        for(int i=1;i<=n;++i){
            int x;
            scanf("%d",&x);
            if(x > maxs[1]) printf("-1\n");
            else printf("%d\n",query(x,1,h,1));
        }
    }
}

 

posted @ 2015-01-28 09:47  fish7  阅读(142)  评论(0编辑  收藏  举报