动态连续区间和查询,Binary Index Tree 算法
2012-11-18 15:44
387 查看
给定N元数组A[0]...A[N-1],设计一个数据结构,支持两种操作:
1. add(i,v) 将A[i]元素值增加v,下标i区间为[0..N-1]
2. sum(L,R) 查询连续区间和 A[L] + A[L+1] + ... + A[R], 下标L,R区间为[0..N-1]
二叉索引树 Binary Index Tree 支持动态连续区间和的查询,BIT含有N个结点,每个结点存储一段区间的和。每次更新数组A的一个元素,只需要更新BIT中的LogN个结点;每次查询A的前缀区间和,只需要查询BIT中的LogN个节点;
BIT树用数组表示,下标区间为[1..N],左孩子i其父结点为i+lowbit(i),右孩子i其父节点为i-lowbit(i),每个BIT结点i代表的区间和为A[i-lowbit(i)+1] + A[i-lowbit(i)+2] + ... + A[i]。其中lowbit(i)=i&(-i)即i的最低非0位代表的值(1,2,4,8,...)。
1. add(i,v) 将A[i]元素值增加v,下标i区间为[0..N-1]
2. sum(L,R) 查询连续区间和 A[L] + A[L+1] + ... + A[R], 下标L,R区间为[0..N-1]
二叉索引树 Binary Index Tree 支持动态连续区间和的查询,BIT含有N个结点,每个结点存储一段区间的和。每次更新数组A的一个元素,只需要更新BIT中的LogN个结点;每次查询A的前缀区间和,只需要查询BIT中的LogN个节点;
BIT树用数组表示,下标区间为[1..N],左孩子i其父结点为i+lowbit(i),右孩子i其父节点为i-lowbit(i),每个BIT结点i代表的区间和为A[i-lowbit(i)+1] + A[i-lowbit(i)+2] + ... + A[i]。其中lowbit(i)=i&(-i)即i的最低非0位代表的值(1,2,4,8,...)。
package ProgrammingContest; public class BinaryIndexTree { private int N = 0; private int[] A = null; private int[] C = null; public BinaryIndexTree(int[] A) { this.A = A; N = A.length; init(A); } // 更新一个元素,下标范围[0..N-1] private void add(int i, int v) { i++; // 下标范围转换为[1..N] while (1 <= i && i <= N) { C[i] += v; i += lowBit(i); } } // 取一个元素,下标范围[0..N-1] public int get(int i) { return A[i]; } // 初始化BinaryIndexTree即数组C public void init(int[] A) { C = new int[A.length + 1]; for (int i = 0; i < C.length; i++) C[i] = 0; for (int i = 0; i < A.length; i++) { add(i, A[i]); } } private int lowBit(int x) { return x & (-x); } // 设置A[i], 下标范围[0..N-1] public void set(int i, int v) { int delta = v - A[i]; A[i] = v; add(i, delta); } // 求前缀和A[0]+...+A[i] public int sum(int i) { i++; // 下标范围转换为[1..N] int sum = 0; while (i >= 1) { sum += C[i]; i -= lowBit(i); } return sum; } // 查询区间[L,R]所有元素的和,下标范围[0..N-1] public int query(int L, int R) { int res = sum(R) - sum(L) + A[L]; return res; } // 测试 public static void main(String[] args) { int[] x = { 2, 1, 3, 4, 5 }; BinaryIndexTree bit = new BinaryIndexTree(x); for ( int i = 0; i< x.length; i++ ) { System.out.println(bit.query(0, i)); } } }
相关文章推荐
- GSS1 - Can you answer these queries I(动态查询区间最大连续和)
- 算法训练 1 区间k大数查询
- 算法分析与设计——LeetCode Problem.98 Validate Binary Search Tree
- 算法训练 区间k大数查询
- 算法系列——Binary Tree Zigzag Level Order Traversal
- Convert Sorted List to Binary Search Tree [leetcode] O(n)的算法
- [LeetCode] Binary Tree Longest Consecutive Sequence 二叉树最长连续序列
- 【暑假】[实用数据结构]动态连续和查询问题
- 通过分析 JDK 源代码研究 TreeMap 红黑树算法实现 refer from http://www.ibm.com/developerworks/cn/java/j-lo-tree/index.html?ca=drs-
- 算法课第三周Validate Binary Search Tree
- 【LeetCode-面试算法经典-Java实现】【105-Construct Binary Tree from Preorder and Inorder Traversal(构造二叉树)】
- LA3938 线段树 动态求区间最大连续和
- 区间信息的维护和查询系列算法-树状数组
- UVa 10304 Optimal Binary Search Tree(区间DP)
- 简单的几道算法题_About Binary Tree
- 算法训练1.区间k最大数查询(排序 查找)
- 算法系列——Binary Tree Preorder Traversal
- 【LeetCode-面试算法经典-Java实现】【107-Binary Tree Level Order Traversal II(二叉树层序遍历II)】
- 【算法作业4】LeetCode 104. Maximum Depth of Binary Tree
- Rank-Tree带动态查询删除 Splay