HDU2795ビルボードの問題解決

HDU2795ビルボード

例の問題セグメントツリーコレクション

問題の意味:H角柱W行、ストライプサイズMの内部に水平に配置され、1 * L [i]は小さな矩形のフィットは、出力線の最小数は下に置くことができれば、しない重なり、出力はしないフィット感であります-1

時間分に取ってのみM矩形、m行(H大きな範囲)のみ最大、M以来

メンテナンス間隔最大の各行の値と、次に残り、左の部分木の代表の最大範囲内のクエリ>は、再帰的、左サブツリーを長さを必要に応じて、長さが十分でない場合、そうでない場合は右の部分木と考え、答えは - 1

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
inline void read (int &x) {
    char ch = getchar(); x = 0;
    while (!isdigit(ch)) ch = getchar();
    while (isdigit(ch))  x = x * 10 + ch - 48, ch = getchar();
}
inline int print (int x) {
    if (x < 0) putchar ('-'), x = -x;
    if (x > 9) print (x / 10);
    putchar (x % 10 + 48);
}
int h, w, n, val, c[N << 2];
#define ls p << 1
#define rs p << 1 | 1
inline int Max (int a, int b) {return a > b ? a : b;}
int query (int p, int l, int r, int val) {
    if (l == r) {
        if (c[p] >= val) {c[p] -= val; return l;}
        else return -1;
    }
    int mid (l + r >> 1), ans (-1);
    if (c[ls] >= val) ans = query (ls, l, mid, val);
    else if (c[rs] >= val) ans = query (rs, mid + 1, r, val);
    c[p] = Max (c[ls], c[rs]);
    return ans;
}
int main() {
    while (~scanf ("%d %d %d", &h, &w, &n)) {
        if (n < h) h = n;
        for (int i = 1; i <= (h << 2); ++i) c[i] = w;
        for (int i = 1; i <= n; ++i) {
            read (val);
            if (val > w) puts ("-1");
            else print (query (1, 1, h, val)), puts ("");
        }
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/whx666/p/12041534.html