307.区域和检索 - 数组可修改(线段树)

b站视频详解线段树
class NumArray {
private int[] tree;
private int[] nums;
private int n;
private void buildTree(int node, int start, int end){
if(start == end){
tree[node] = nums[start];
return;
}
int mid = (start + end) / 2;
int left = node * 2 + 1;
int right = node * 2 + 2;
buildTree(left, start, mid);
buildTree(right, mid + 1, end);
tree[node] = tree[left] + tree[right];
}
private void updateTree(int node, int start, int end, int idx, int val){
if(start > end) return;
if(start == end){
nums[idx] = val;
tree[node] = val;
}else{
int mid = (start + end) / 2;
int left = node * 2 + 1;
int right = node * 2 + 2;
if(idx >= start && idx <= mid){
updateTree(left, start, mid, idx, val);
}else{
updateTree(right, mid + 1, end, idx, val);
}
tree[node] = tree[left] + tree[right];
}
}
private int query(int node, int start, int end, int L, int R){
if(L > end || R < start) return 0;
if(start == end) return tree[node];
if(L <= start && end <= R){
return tree[node];
}else{
int mid = (start + end) / 2;
int left = node * 2 + 1;
int right = node * 2 + 2;
int ls = query(left, start, mid, L, R);
int rs = query(right, mid + 1, end, L, R);
return ls + rs;
}
}
public NumArray(int[] nums) {
this.n = nums.length;
tree = new int[n * 4];
this.nums = nums;
buildTree(0, 0, n - 1);
}
public void update(int index, int val) {
updateTree(0, 0, n - 1, index, val);
}
public int sumRange(int left, int right) {
return query(0, 0, n - 1, left, right);
}
}