HDU 2795 Billboard(线段树)

题目链接:HDU 2795 Billboard

线段树单点更新。

线段树记录某一行还剩下多少个空余位置,有空余位置的话先放左边那棵树。注意h的范围不会超过n的。

我感觉这道题有bug。。开始我写的是h = min(h, n),不通过,然后我看讨论版上有人说改成if(h > 200000) h = 200000,然后果然就过了,后来看了看别人代码,发现人家的min可以通过,但是输出-1时候要直接在main函数内判断,不能像我那样在函数里返回-1,诡异。

下面两份代码都是对的。

#include <iostream>
#include <stdio.h>

using namespace std;
const int MAX_N = 200000 + 100;

struct Node
{
    int l, r, value;
};
Node node[MAX_N << 2];
int h, w, n;

void build(int l, int r, int i)
{
    node[i].l = l;
    node[i].r = r;
    if(l == r)
    {
        node[i].value = w;
        return ;
    }
    int mid = (l + r) >> 1;
    build(l, mid, i << 1);
    build(mid + 1, r, i << 1 | 1);
    node[i].value = max(node[i << 1].value, node[i << 1 | 1].value);
}
int query(int i, int wi)
{
    int res;
    if(node[i].l == node[i].r)
    {
        node[i].value -= wi;
        return node[i].l;
    }
    /*if(node[1].value < wi)
        return -1;*/
    if(node[i << 1].value >= wi)
        res = query(i << 1, wi);
    else
        res = query(i << 1 | 1, wi);
    node[i].value = max(node[i << 1].value, node[i << 1 | 1].value);
    return res;
}
int main()
{
    //freopen("in.txt", "r", stdin);
    while(scanf("%d%d%d", &h, &w, &n) != EOF)
    {
        h = min(h, n);
        /*if(h > MAX_N)
            h = MAX_N;*/
        build(1, h, 1);
        int wi;
        for(int i = 0; i < n; i++)
        {
            scanf("%d", &wi);
			if(node[1].value < wi)
            {
                printf("-1\n");
                continue;
            }
            printf("%d\n", query(1, wi));
        }
    }
    return 0;
}

#include <iostream>
#include <stdio.h>

using namespace std;
const int MAX_N = 200000 + 100;

struct Node
{
    int l, r, value;
};
Node node[MAX_N << 2];
int h, w, n;

void build(int l, int r, int i)
{
    node[i].l = l;
    node[i].r = r;
    if(l == r)
    {
        node[i].value = w;
        return ;
    }
    int mid = (l + r) >> 1;
    build(l, mid, i << 1);
    build(mid + 1, r, i << 1 | 1);
    node[i].value = max(node[i << 1].value, node[i << 1 | 1].value);
}
int query(int i, int wi)
{
    int res;
    if(node[i].l == node[i].r)
    {
        node[i].value -= wi;
        return node[i].l;
    }
    if(node[1].value < wi)
        return -1;
    if(node[i << 1].value >= wi)
        res = query(i << 1, wi);
    else
        res = query(i << 1 | 1, wi);
    node[i].value = max(node[i << 1].value, node[i << 1 | 1].value);
    return res;
}
int main()
{
    //freopen("in.txt", "r", stdin);
    while(scanf("%d%d%d", &h, &w, &n) != EOF)
    {
        //h = min(h, n);
        if(h > MAX_N)
            h = MAX_N;
        build(1, h, 1);
        int wi;
        for(int i = 0; i < n; i++)
        {
            scanf("%d", &wi);
            printf("%d\n", query(1, wi));
        }
    }
    return 0;
}


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