HDOJ 2795 Billboard

看了notonlysuccess的博客

线段树维护最大值,这道题需要注意的是当h>n时,令h = n,原因是如果wi都小于w,最多只用前n行,反之一定结果是-1。

# include <cstdio>

int h, w, n, wi;
int m[4 * 200010];

int Max(int x, int y)
{
    return x > y ? x : y;
}

void update(int r)
{
    m[r] = Max(m[r << 1], m[r << 1 | 1]);
}

void build(int x, int y, int r)
{
    m[r] = w;
    if (x >= y) return ;
    int mid = (x+y) >> 1, ls = r << 1, rs = r << 1 | 1;
    build(x, mid, ls);
    build(mid+1, y, rs);
    update(r);
}

void query(int x, int y, int r)
{
    if (x == y) {m[r] -= wi; printf("%d\n", x); return ;}
    int mid = (x+y) >> 1, ls = r << 1, rs = r << 1 | 1;
    if (m[ls] < wi) query(mid+1, y, rs);
    else query(x, mid, ls);
    update(r);
}

void solve(void)
{
    if (h > n) h = n;
    build(1, h, 1);
    while (n--)
    {
        scanf("%d", &wi);
        if (m[1] < wi)
            puts("-1");
        else
            query(1, h, 1);
    }
}

int main()
{
    while (~scanf("%d%d%d", &h, &w, &n))
        solve();
    
    return 0;
}

 

posted on 2012-08-20 09:16  getgoing  阅读(231)  评论(0编辑  收藏  举报

导航