有 N 個敵兵營地,初始各有若干兵力。支援三種操作:
Add i v:第 i 營地增加 v 兵力Sub i v:第 i 營地減少 v 兵力Query i j:查詢區間 [i, j] 總兵力多測試案例,每案例以 End 結束。N ≤ 50,000,操作數未限但隱含 ≤ 50,000。
經典單點更新、區間查詢場景,樹狀數組(Binary Indexed Tree, BIT)完美契合:
add(i, v):O(log N)sum(i)(前綴和):O(log N)[l, r] = sum(r) - sum(l-1)/* HDU 1166 敵兵布陣 - BIT */
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 50000 + 5;
int c[MAXN], n;
int lowbit(int x) { return x & -x; }
void add(int i, int val) {
for (; i <= n; i += lowbit(i)) c[i] += val;
}
int sum(int i) {
int s = 0;
for (; i > 0; i -= lowbit(i)) s += c[i];
return s;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T; cin >> T;
for (int cas = 1; cas <= T; ++cas) {
cin >> n;
fill(c, c + n + 1, 0);
for (int i = 1; i <= n; ++i) {
int x; cin >> x; add(i, x);
}
cout << "Case " << cas << ":\n";
string op;
while (cin >> op) {
if (op[0] == 'E') break; // End
int x, y; cin >> x >> y;
if (op[0] == 'A') add(x, y);
else if (op[0] == 'S') add(x, -y);
else if (op[0] == 'Q') cout << sum(y) - sum(x - 1) << "\n";
}
}
return 0;
}
add(i, x) 建樹,O(N log N);也可用 O(N) 建樹優化,但 N=5e4 無壓力。op[0] 區分 'A'/'S'/'Q'/'E',簡潔高效。fill(c, c+n+1, 0) 重置。O(N log N)O(log N)O(N)。HDU 1166 是樹狀數組教科書級入門題。它展示了 BIT 在「動態單點修改 + 區間和查詢」場景下的極致簡潔與高效。掌握 lowbit、add、sum 三個核心函數,即可輕鬆解決此類問題。建議初學者背誦模板,並理解「為什麼 i += lowbit(i) 能覆蓋所有包含 i 的區間」的直觀幾何意義。