开始学习线段树,这是线段树的第一道题。
看了这位神牛的代码,然后理解了一遍,然后自己敲了一遍(几乎完全一样)。
http://www.notonlysuccess.com/index.php/segment-tree-complete/
#include <iostream> #include <cstdio> using namespace std; #define MAXN 50005 int sum[MAXN << 2]; void pushUp(int rt) { sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; } void build(int l, int r, int rt) { if (l == r) { scanf ("%d", &sum[rt]); return; } int m = (l + r) >> 1; build(l, m, rt << 1); build(m + 1, r, rt << 1 | 1); pushUp(rt); } void update(int p, int add, int l, int r, int rt) { if (l == r) { sum[rt] += add; return; } int m = (l + r) >> 1; if (p <= m) update(p, add, l, m, rt << 1); else update(p, add, m + 1, r, rt << 1 | 1); pushUp(rt); } int query(int l, int r, int rt, int L, int R) { if (l >= L && r <= R) return sum[rt]; int ans = 0; int m = (l + r) >> 1; if (m >= L) ans += query(l, m, rt << 1, L, R); if (m < R) ans += query(m + 1, r, rt << 1 | 1, L, R); return ans; } int main() { int t, cas, n; scanf ("%d", &t); for (cas = 1; cas <= t; cas++) { scanf ("%d", &n); build(1, n, 1); printf ("Case %d:\n", cas); char op[10]; while (true) { //getchar(); scanf("%s", op); if (op[0] == 'E') break; int a, b; scanf ("%d %d", &a, &b); if (op[0] == 'S') update(a, -b, 1, n, 1); else if (op[0] == 'A') update(a, b, 1, n, 1); else printf ("%d\n", query(1, n, 1, a, b)); } } return 0; }