垂直分佈的木板,每板有高度 h、左右端點 xl, xr、能量值 val(正/負)。角色從最高板(初始能量 100)開始,每次從當前板左/右端點垂直下落,落到最近的下方板。可選擇左/右端點下落。若落地時能量 ≤ 0 則失敗(輸出 -1),否則求最大最終能量。
對每塊板的左右端點,需知下落會落在哪塊板上。暴力 O(N²) 過慢(N≤100,000)。
h 升序排序所有板(從低向高處理)i 時:
query(xl) → 落在板 L,記 left[i] = Lquery(xr) → 落在板 R,記 right[i] = Rupdate(xl, xr, i) —— 將區間染為板 i 的顏色val=0),初始染色整個 x 軸為 0按高度降序(從高向低)處理:
dp[i] = 從板 i 開始能獲得的最大額外能量 dp[left[i]] = max(dp[left[i]], dp[i] + val[left[i]]); dp[right[i]] = max(dp[right[i]], dp[i] + val[right[i]]);
初始 dp[top] = 100。最終答案 dp[0](地面),若 ≤0 輸出 -1。
struct SegNode { int l, r, color; } tree[4*MAXX];
void pushdown(int v) {
if (tree[v].color != -1) {
tree[v<<1].color = tree[v<<1|1].color = tree[v].color;
tree[v].color = -1;
}
}
void update(int v, int L, int R, int color) {
if (L <= tree[v].l && tree[v].r <= R) {
tree[v].color = color; return;
}
pushdown(v);
int mid = (tree[v].l + tree[v].r) >> 1;
if (R <= mid) update(v<<1, L, R, color);
else if (L > mid) update(v<<1|1, L, R, color);
else {
update(v<<1, L, mid, color);
update(v<<1|1, mid+1, R, color);
}
}
int query(int v, int pos) {
if (tree[v].color != -1) return tree[v].color;
int mid = (tree[v].l + tree[v].r) >> 1;
return pos <= mid ? query(v<<1, pos) : query(v<<1|1, pos);
}