树状数组维护区间最值
一, 工作原理
树状数组是一种支持单点修改和区间查询的数据结构。普通树状数组维护的信息及运算要满足结合律且可差分,如加法(和)、乘法(积)、异或等。
——OI WIKI
img
数组中下标为x的元素管辖区间为[x-lowbit(x)+1,x]
二,建树
1 2 3 4 5 6 7 8 9
| void build() { for (int i = 1; i <= n; i++) { tree[i] = max(tree[i], a[i]); int j = i + lowbit(i); if (j <= n) tree[j] = max(tree[j], tree[i]); } }
|
三,单点修改
img
1 2 3 4 5 6 7 8 9 10 11
| void add(int x, int c) { tree[x] = a[x] = c; for (int i = 1; i < lowbit(x); i <<= 1) tree[x] = max(tree[x], tree[x - i]);
for (int i = x; i + lowbit(i) <= n; i += lowbit(i)) { int j = lowbit(i); tree[i + j] = max(tree[i + j], tree[i]); } }
|
四,区间查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| int query(int l, int r) { int res = -INF; while (l <= r) { for (; l <= r && r - lowbit(r) + 1 >= l; r -= lowbit(r)) { res = max(tree[r], res); }
if (l > r) break; res = max(a[r], res); r--; } return res; }
|