线段树和树状数组
线段树完全包含树状数组
相比较于线段树,树状数组的代码很短,效率更高
树状数组
应用:快速求前缀和
时间复杂度:O(logN)
操作:
1.给某个位置上的数加上一个数 -- 单点修改
2.求某一个前缀和 -- 区间查询
注意事项:树状数组的下标从1开始;树状数组是一维数组
假设原数组为a[]
树状数组为c[]
如果i为奇数 : c[i] = a[i]
c[2] = a[2] + c[1]
c[4] = a[4] + c[3] + c[2]
如图所示为树状数组的结构
总结: x的二进制表示最后有k个零 – c[x] = (x - 2^k(lowbit) , x]
lowbit(x) 运算 :lowbit(x) = 2^k = x & -x
//求前缀和代码
int res = 0;
for(int i = x; i > 0; i -= lowbit(i)) res += c[i];
return res;
//a[x] + v
for(int i = x; i <= n; i += lowbit(i)) c[x] + v