树状数组
概念
树状数组(Fenwick Tree)是一种数组实现的树状结构,常用于解决前缀和问题。它能够在O(log n)的时间内进行单点更新与区间查询操作,特别适用于在动态变化的数组中进行频繁的前缀和查询和更新。
通常需要对输入数据进行离散化,因为数据通常是不连续,而数组要求索引连续
- 操作
- 单点修改:更改数组中一个元素的值
- 区间查询:查询一个区间内所有元素的和
范围:[1, n];
例如:7(111)
单点修改:111 -> 1000
区间查询:111 -> 110 -> 100
前缀和模板
注意不能add(0, val)
,无法跳出循环,因为lowbit(0) = 0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class FenwickTree { int[] tr; public FenwickTree(int[] nums) { this.tr = new int[nums.length+1]; for (int i = 0; i < nums.length; i++) { add(i+1, nums[i]); } } public int lowbit(int x) { return x & (-x); } public void add(int i, int val) { while (i < tr.length) { tr[i] += val; i += lowbit(i); } } public int query(int i) { int res = 0; while (i > 0) { res += tr[i]; i -= lowbit(i); } return res; } }
|
前缀最大值模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class FenwickTree { int[] tr; public FenwickTree(int n) { this.tr = new int[n]; Arrays.fill(tr, -1); } public int lowbit(int x) { return x & (-x); } public void add(int i, int val) { while (i < tr.length) { tr[i] = Math.max(tr[i], val); i += lowbit(i); } } public int query(int i) { int res = -1; while (i > 0) { res = Math.max(res, tr[i]); i -= lowbit(i); } return res; } }
|
相关题解