刷题遇到树状数组,在这里做一下总结。
树状树状是一种数据结构,可以在o(logn)的时间内对元素进行修改和求和
1、根据元素数组构建树状数组
数组A为原数组,数组C为树状数组
C1 = A1
C2 = A1 + A2
C3 = A3
C4 = A1 + A2 + A3 + A4
C5 = A5
C6 = A5 + A6
C7 = A7
C8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8
C[x]求解:
将x转换为二进制1***1000,C[1***1000]=A[1***0001]+A[1***0010]+.....+A[1***1000]即获得x的二进制中最后一位1的位数k,求从A[x]开始向左数的2的k次方个数组的和。
int lowbit(int n)
{
return n& (-n);
//or return n&(n^(n-1));
}
当原数组进行更新时,树状数组与原数组有关的每一个数组都需要进行更新:
void update(int i, int val) //将第i个元素增加val
{
//与A[i]相关的所有的C[i]更新
while(i <= n)
{
C[i] += val;
i += lowbit(i); //下一个
}
}
求数组前n项和:
int Sum(int i) //求前i项的和
{
int s = 0;
while(i > 0)
{
s += C[i];
i -= lowbit(i); //去掉i的二进制最后一个
}
return s;
}
因篇幅问题不能全部显示,请点此查看更多更全内容