有 N 名學生(N ≤ 200,000),初始成績已知。支援 M 次操作(M < 50,000):
Q A B:查詢區間 [A, B] 最大成績U A B:將學生 A 成績更新為 B每個節點存儲區間 [l, r] 的最大值 maxVal。
struct Node {
int l, r;
int maxVal;
} tree[MAXN * 4];
void build(int l, int r, int idx) {
tree[idx].l = l; tree[idx].r = r;
tree[idx].maxVal = 0;
if (l == r) return;
int mid = (l + r) >> 1;
build(l, mid, idx << 1);
build(mid + 1, r, idx << 1 | 1);
}
void update(int pos, int val, int idx) {
if (tree[idx].l == tree[idx].r) {
tree[idx].maxVal = val;
return;
}
int mid = (tree[idx].l + tree[idx].r) >> 1;
if (pos <= mid) update(pos, val, idx << 1);
else update(pos, val, idx << 1 | 1);
tree[idx].maxVal = max(tree[idx<<1].maxVal, tree[idx<<1|1].maxVal);
}
int query(int L, int R, int idx) {
if (tree[idx].l == L && tree[idx].r == R)
return tree[idx].maxVal;
int mid = (tree[idx].l + tree[idx].r) >> 1;
if (R <= mid) return query(L, R, idx << 1);
if (L > mid) return query(L, R, idx << 1 | 1);
return max(query(L, mid, idx << 1), query(mid + 1, R, idx << 1 | 1));
}
#include#include #include using namespace std; const int MAXN = 200010; struct Node { int l, r, maxVal; } tree[MAXN * 4]; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; while (scanf("%d%d", &n, &m) == 2) { build(1, n, 1); for (int i = 1; i <= n; ++i) { int score; scanf("%d", &score); update(i, score, 1); } char op; for (int i = 0; i < m; ++i) { scanf(" %c%d%d", &op, &a, &b); if (op == 'U') update(a, b, 1); else if (op == 'Q') printf("%d\n", query(a, b, 1)); } } return 0; }
| 特性 | HDU 1166 | HDU 1754 |
|---|---|---|
| 查詢類型 | 區間和 | 區間最大值 |
| 合併操作 | sum = left + right | maxVal = max(left, right) |
| 初始化 | 建樹時直接賦值 | 建樹後逐個 update |
| 輸入結束 | End 指令 | EOF (while scanf==2) |
ans 遞歸更新,避免返回值傳遞開銷scanf,cin 會 TLE4*N(800,000+)