//线段树 用来存取1-n 这条线段中 整数点出现的次数,已经一段中所有点出现的次数 //扩展 可以把整数点映射成n个实体, 每个实体会存放着一点资源, 线段树在大规模读取连续数的时候存在着优势 public class LineTree { int[] tree; int size; public LineTree(int n) { tree = new int[n * 4 + 1]; // 抛弃掉0点 方便index的扩张 e.g 1的子节点为2, 3 2的子节点为3 4 size = n; } public static void main(String[] args){ //test case acm_116 LineTree lineTree = new LineTree(5); lineTree.Update(1, 1); lineTree.Update(2, 2); lineTree.Update(3, 3); lineTree.Update(4, 4); lineTree.Update(5, 5); System.out.println(lineTree.Query(1, 3)); lineTree.Update(1, 2); System.out.println(lineTree.Query(1, 3)); lineTree.Update(2, 3); System.out.println(lineTree.Query(1, 2)); System.out.println(lineTree.Query(1, 5)); } public void init() throws Exception { if (tree == null) { throw new Exception("tree 未初始化"); } for (int i = 0; i < tree.length; i++) { tree[i] = 0; } size = 0; } // 在这条线段中的n节点 插入权值value; public void Update(int n, int value) { Update(1, 1, size, n, value); } private void Update(int index, int left, int right, int n, int value) { tree[index] += value; if (left == right) { return; } else { int mid = (left + right) >> 1; if (mid >= n) { Update(index << 1, left, mid, n, value); } else { Update(index << 1 | 1, mid + 1, right, n, value); } } } // 差选线段起止之间的权值和 public int Query(int start, int end) { return Query(1, 1, size, start, end); } private int Query(int index, int left, int right, int start, int end) { // System.out.println(left +" "+ right); int sum = 0; if (left >= start && right <= end) { return tree[index]; } int mid = (left + right) >> 1; if (mid >= start && left<= end) { sum += Query(index << 1, left, mid, start, end); } if (mid <= end && right >= start) { sum += Query(index >> 1 | 1, mid + 1, right, start, end); } return sum; } }
java 实现线段树_java代码实现线段树
最新推荐文章于 2023-04-05 22:02:25 发布