structnode { int l, r; // 表示两个儿子 int val; // 表示维护的信息(如和,最小值等) };
画出来差不多是这个样子:
支持操作
单点修改:修改一个数值后,容易发现至多影响 log n 个点的信息
1 2 3 4 5 6 7 8
int tr[N * 4]; voidchange(int o, int pos, int val, int l, int r) { if(l == r) tr[o] = val; // 找到这个点了 int mid = l + r >> 1; if(pos <= mid) change(o * 2, pos, val, l, mid); else change(o * 2 + 1, pos, val, mid + 1, r); }
区间查询 将区间拆分成极大的维护的区间(共θ(logn)个), 再把这些信息合并
1 2 3 4 5 6 7 8
intquery(int o, int l, int r, int left, int right) { if(l == r) return tr[o]; int m = l + r >> 1; int ans = 0; if(left <= l && right >= mid) ans = query(o * 2, l, mid, left, right); if(left <= mid+1 && right >= r) ans += query(o * 2 + 1, mid + 1, r, left, right); }