思路:
基本的线段树操作:单点更新,区间求和
#include <cstdio> #include <cstdlib> #include <cstring> #define lhs l, m, rt << 1 #define rhs m + 1, r, rt << 1 | 1 const int maxn = 50010; int seg[maxn << 2]; void PushUp(int rt) { seg[rt] = seg[rt << 1] + seg[rt << 1 | 1]; } void Build(int l, int r, int rt) { if (l == r) scanf("%d", &seg[rt]); else { int m = (l + r) >> 1; Build(lhs); Build(rhs); PushUp(rt); } } void Update(int p, int delta, int l, int r, int rt) { if (l == r) seg[rt] += delta; else { int m = (l + r) >> 1; if (p <= m) Update(p, delta, lhs); else Update(p, delta, rhs); PushUp(rt); } } int Query(int beg, int end, int l, int r, int rt) { if (beg <= l && r <= end) return seg[rt]; int m = (l + r) >> 1; int ret = 0; if (beg <= m) ret += Query(beg, end, lhs); if (end > m) ret += Query(beg, end, rhs); return ret; } int main() { int cases; scanf("%d", &cases); for (int t = 1; t <= cases; ++t) { int n; scanf("%d", &n); Build(1, n, 1); printf("Case %d:\n", t); char op[16]; while (scanf("%s", op) && op[0] != 'E') { int a, b; scanf("%d %d", &a, &b); if (op[0] == 'Q') printf("%d\n", Query(a, b, 1, n, 1)); else if (op[0] == 'A') Update(a, b, 1, n, 1); else if (op[0] == 'S') Update(a, -b, 1, n, 1); } } return 0; }