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;
}