Segment Tree & Binary Indexed Tree
Range query when input can be updated(在线修改并查询), otherwise prefixSum should be good enough
线段树的作用,可以解决的问题
线段数基本操作
线段数应用
Last updated
Range query when input can be updated(在线修改并查询), otherwise prefixSum should be good enough
Last updated
public SegmentTreeNode build(int start, int end) {
// [10, 4] return null
if(start > end) return null;
SegmentTreeNode root = new SegmentTreeNode(start, end);
if(start == end) return root;
int mid = start + (end - start)/2;
root.left = build(start, mid);
root.right = build(mid + 1, end);
return root;
}public SegmentTreeNode build(int[] A) {
// write your code here
if(A.length < 1) return null;
return buildHelper(A, 0, A.length - 1);
}
private SegmentTreeNode buildHelper(int[] A, int start, int end){
if(start > end) return null;
if(start == end) return new SegmentTreeNode(start, end, A[start]);
int mid = start + (end - start) /2 ;
SegmentTreeNode left = buildHelper(A, start, mid);
SegmentTreeNode right = buildHelper(A, mid + 1, end);
SegmentTreeNode root = new SegmentTreeNode(start, end, Math.max(left.max, right.max));
root.left = left;
root.right = right;
return root;
}public void modify(SegmentTreeNode root, int index, int value) {
// write your code here
if(root == null) return;
if(index < root.start || index > root.end) return;
if(index == root.start && index == root.end){
//不能写成root.max = Math.max(root.max, vlaue)
//这个时候必须改变值
root.max = value;
return;
}
modify(root.left, index, value);
modify(root.right, index, value);
root.max = Math.max(root.left.max, root.right.max);
}public int query(SegmentTreeNode root, int start, int end) {
// write your code here
if(start > root.end || end < root.start) return Integer.MIN_VALUE;
start = Math.max(start, root.start);
end = Math.min(end, root.end);
if(start == root.start && end == root.end) return root.max;
int leftMax = query(root.left, start, end);
int rightMax = query(root.right, start, end);
return Math.max(leftMax, rightMax);
}public int query(SegmentTreeNode root, int start, int end) {
// write your code here
if(root == null) return 0;
if(start > root.end || end < root.start) return 0;
start = Math.max(start, root.start);
end = Math.min(end, root.end);
if(start == root.start && end == root.end) return root.count;
int leftCnt = query(root.left, start, end);
int rightCnt = query(root.right, start, end);
return leftCnt + rightCnt;
}class NumArray {
public class segmentTreeNode {
int sum;
segmentTreeNode left;
segmentTreeNode right;
int begin;
int end;
public segmentTreeNode(int begin, int end) {
this.begin = begin;
this.end = end;
left = right = null;
sum = 0;
}
}
//build
segmentTreeNode build(int[] arr, int begin, int end) {
if (begin > end) {
return null;
}
segmentTreeNode root = new segmentTreeNode(begin, end);
if (begin == end) {
root.sum = arr[begin];
return root;
}
int mid = (end - begin) / 2 + begin;
root.left = build(arr, begin, mid);
root.right = build(arr, mid + 1, end);
root.sum = root.left.sum + root.right.sum;
return root;
}
//modify
public void modify(segmentTreeNode root, int idx, int val) {
if (root.end == idx && root.begin == idx) {
root.sum = val;
return;
}
int mid = (root.end - root.begin) / 2 + root.begin;
if (root.begin <= idx && idx <= mid) {
modify(root.left, idx, val);
}
if (mid < idx && idx <= root.end) {
modify(root.right, idx, val);
}
root.sum = root.left.sum + root.right.sum;
}
//query
public int query(segmentTreeNode root, int begin, int end) {
if (root.begin > end || root.end < begin) {
return 0;
}
if (begin <= root.begin && end >= root.end) {
return root.sum;
}
return query(root.left, begin, end) + query(root.right, begin, end);
}
segmentTreeNode node;
int[] arr;
public NumArray(int[] nums) {
// node = new segmentTreeNode(0, nums.length - 1);
arr = nums;
node = build(arr, 0, nums.length - 1);
}
public void update(int i, int val) {
modify(node, i, val);
}
public int sumRange(int i, int j) {
return query(node, i, j);
}
}public class Solution {
/**
*@param A, queries: Given an integer array and an query list
*@return: The result list
*/
public class segmentTreeNode{
int start;
int end;
int min;
segmentTreeNode left;
segmentTreeNode right;
public segmentTreeNode(int start, int end, int min){
this.start = start;
this.end = end;
this.min = min;
}
}
public segmentTreeNode build(int[] A, int start, int end){
if(start < 0 || end >= A.length || start > end) return null;
if(start == end) {
return new segmentTreeNode(start, end, A[start]);
}
int mid = start + (end - start) / 2;
segmentTreeNode left = build(A, start, mid);
segmentTreeNode right = build(A, mid + 1, end);
segmentTreeNode root = new segmentTreeNode(start, end, Math.min(left.min, right.min));
root.left = left;
root.right = right;
return root;
}
public int queryMin(segmentTreeNode root, int start, int end){
if(start > root.end || end < root.start) return Integer.MAX_VALUE;
start = Math.max(start, root.start);
end = Math.min(end, root.end);
if(start == root.start && end == root.end) return root.min;
int left = queryMin(root.left, start, end);
int right = queryMin(root.right, start, end);
return Math.min(left, right);
}
public ArrayList<Integer> intervalMinNumber(int[] A,
ArrayList<Interval> queries) {
// write your code here
ArrayList<Integer> res = new ArrayList<>();
if(A == null || A.length < 1 || queries == null || queries.size() < 1) return res;
segmentTreeNode root = build(A, 0, A.length - 1);
for(Interval interval : queries){
int start = interval.start;
int end = interval.end;
int min = queryMin(root, start, end);
res.add(min);
}
return res;
}
}