A[]数组为存储原来的值得数组,C[]为树状数组
c8 = c4+c6+c7+a8,c6 = c5+a6, 。。。
维护和查询都是O(lgn)的复杂度,复杂度取决于最坏的情况,也是O(lgn)
public class BinaryIndexedTree {
int[] nums;
int[] sums;// 实际上存的是C(i), C(i)包含2^k个元素
public BinaryIndexedTree(int[] nums) throws Exception {
int n = nums == null ? 0 : nums.length;
if (n == 0) {
throw new Exception("The input array should not be null or empty");
}
this.nums = nums;
sums = new int[n + 1];
for (int i = 0; i < n; i++) {// T(n) = O(nlogn)
add(i + 1, nums[i]);
}
}
// 从叶子节点向上更新父节点
public void update(int i, int val) {// O(logn)
add(i + 1, val - nums[i]);
nums[i] = val;
}
public int sumRange(int i, int j) {// O(logn)
return nums == null ? 0 : sum(j + 1) - sum(i);
}
// T(n) = O(logn)
private void add(int index, int value) {
while (index <= nums.length) {
sums[index] += value;
index += lowbit(index);// 把末尾1补为0的过程, 向下一个C[t]
}
}
private int lowbit(int x) {
return (x & -x);// -x == (~x + 1),
}
private int sum(int index) {
int res = 0;
while (index > 0) {
res += sums[index];
index -= lowbit(index);
}
return res;
}
}
http://blog.csdn.net/int64ago/article/details/7429868
http://blog.csdn.net/ljd4305/article/details/10101535