什么是树状数组
可以解决大部分基于区间上的更新以及求和问题。
l o w b i t lowbit lowbit ( x x x & − x -x −x )
解释一:
x x x 的二进制最右边第一个出现的 1 1 1 和后面出现的 0 0 0 组成的 10 10 10 进制数:
l o w b i t ( 6 ) = 110 − > 2 lowbit(6) = 110 -> 2 lowbit(6)=110−>2
l o w b i t ( 8 ) = 1000 − > 8 lowbit(8) = 1000 -> 8 lowbit(8)=1000−>8
解释二:
x x x 的二进制最右边有 k k k 个连续的 0 0 0 , l o w b i t ( x ) = 2 x lowbit(x) = 2^x lowbit(x)=2x ;
树状数组实现
public class TreeArray{
int[] A;//原始数据
int[] C;//树状数组
int n;//数组元素个数
public TreeArray(int[] A){
this.A = new int[A.length];
n = A.length;
C = new int[n+1];
for(int i=1;i<=A.length;i++){
updata(i,A[i-1]);
}
}
public int lowbit(int x){
return x & -x;
}
public void updata(int i,int val){
//原来的值A[i-1],现在的值是val
int data = val - A[i-1];//新旧值之间的差距
A[i-1] = val;
for(int pos = i;pos<=n;pos = pos+lowbit(pos)){
C[pos] += data;
}
}
public int sum(int pos){
int sum = 0;
for(int i=pos;i>=1;i-=lowbit(i)){
sum = sum + C[i];
return sum;
}
}
public int sumRange(int start,int end){
if(start<1 || start>n || end<1 || end>n) return -1;
else
return sum(end) - sum(start-0);
}
}