标签:
树状数组详解:................
如图可知:
为奇数的时候他是代表他本身,而为偶数的时候则是代表着自己以及属于它管辖区域的和。
(1)C[x] 展开以后有多少项?由下面公式计算:
int lowbit(int x) { //计算 C[x] 展开的项数
return x & (-x);
}void add(int pos, int c){
while(pos <= n){
C[pos] += c;
pos += lowbit(pos);//转移到他的父亲节点,如果这个点更新C[4],那么下一个更新的点就是C[8],相当于他的父亲
}
}int sum(int pos){
int ret = 0;
while(pos > 0){
ret += C[pos];
pos -= lowbit(pos);//当你要计算1..6的和时,结果即为C[4] + C[6]
}
}void add(int x, int y, int c){
//如果我改变了C[x][y]这个点,那么接下来C[x][y += lowbit(y)]当做一维数组的话都是要改变一个c的
//接着我们的纵坐标也是要改变的C[x += lowbit(x)][y]也是要改变的,应为他们都包含了C[x][y]这个集合
for(int i = x;i < n;i += lowbit(i)){
for(int j = y; j < n;j += lowbit(j)){
C[i][j] += c;
}
}
}int sum(int x,int y){
int ret = 0;
for(int i = x; i > 0; i -= lowbit(i)){
for(int j = y;j > 0;j -= lowbit(i)){
ret += C[i][j];
}
}
return ret;
}这就是二维树状数组的成型,那么三维以及以上呢,想来大家都已经秒懂了,是的,没错,就是在最外一层加个循环跟一维变为二维原理一样
而对于区间增加以及减少依旧很简答
比如举个例子,我要将[x, y]区间增加d,那么可以先将1....y加上d,然后1.....x减去d
对于二维树状数组的区间更新也是如此
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/qq_18661257/article/details/47347995