第一次学,码住以后还看
让你顿悟树状数组原理与由来 - 此店不售此书的文章 - 知乎
https://zhuanlan.zhihu.com/p/422561589
学习笔记:优美的结构,树状数组 - LinearExpectation的文章 - 知乎
https://zhuanlan.zhihu.com/p/358173145
保留"从低位向高位数,第一个数字1"为运算结果
最低位的 1 所处的位置,对应的就是树从下往上数的层数
class NumArray {
int[] anums;
int[] nums;
int n;
public NumArray(int[] nums) {
this.nums=nums;
n=nums.length;
anums=new int[n+10];
for(int i=0;i<n;i++){
add(i+1,nums[i]);//树状数组从1开始
}
}
public void update(int index, int val) {
int tmp=val-nums[index];
add(index+1,tmp);//更新树状数组
nums[index]=val;//更新原数组
}
public int sumRange(int left, int right) {
return preSum(right+1)-preSum(left);
}
public int lowbit(int x){
return x&(-x);
}
//在index位置加上val
//需要将index上面的节点也都加上val,维持性质
public void add(int index,int val){
for(int x=index;x<=n;x+=lowbit(x)){
anums[x]+=val;
}
}
public int preSum(int index){
int res=0;
for(int x=index;x>0;x-=lowbit(x)){
res+=anums[x];
}
return res;
}
}
/**
* Your NumArray object will be instantiated and called as such:
* NumArray obj = new NumArray(nums);
* obj.update(index,val);
* int param_2 = obj.sumRange(left,right);
*/
分治
class NumArray {
int[] trees;
int n;
public NumArray(int[] nums) {
this.n=nums.length;
this.trees=new int[n*4];
build(0,0,n-1,nums);
}
public void update(int index, int val) {
change(index,val,0,0,n-1);
}
public int sumRange(int left, int right) {
return range(left,right,0,0,n-1);
}
public void build(int node,int s,int e,int[] nums){
if(s>e) return;
if(s==e){
trees[node]=nums[s];
return;
}
int mid=(e-s)/2+s;
build(node*2+1,s,mid,nums);
build(node*2+2,mid+1,e,nums);
trees[node]=trees[node*2+1]+trees[node*2+2];
}
public void change(int index,int val,int node,int s,int e){
if(s==e){
trees[node]=val;
return;
}
int mid=(e-s)/2+s;
if(index<=mid){
change(index,val,node*2+1,s,mid);
}
else{
change(index,val,node*2+2,mid+1,e);
}
trees[node]=trees[node*2+1]+trees[node*2+2];
}
public int range(int left,int right,int node,int s,int e){
if(left==s&&right==e){
return trees[node];
}
int mid=(e-s)/2+s;
if(mid>=right){
return range(left,right,node*2+1,s,mid);
}
else if(mid<left){
return range(left,right,node*2+2,mid+1,e);
}
else{
return range(left, mid, node * 2 + 1, s, mid) + range(mid + 1, right, node * 2 + 2, mid + 1, e);
}
}
}
/**
* Your NumArray object will be instantiated and called as such:
* NumArray obj = new NumArray(nums);
* obj.update(index,val);
* int param_2 = obj.sumRange(left,right);
*/