二维树状数组
-
二维树状数组
二维树状数组实质上是一维树状数组的扩充。
二维树状数组的定义为:C[x] [y] = ∑ a[i][j] , (x -= lowbit(x), y -= lowbit(y), 1≤ i ≤x, 1≤ j ≤y) 。
当 x=1 时,就变成了 C[1] [y] = ∑ a[1][j] , ( y -= lowbit(y), 1≤ j ≤y) 。通过固定 x 的值,就将二维树状数组降到了一维树状数组。
所以,二维树状数组,在固定一个维度时,在另一个维度上看,就是一个一维树状数组,所以说二维树状数组是基于一维树状数组的,仅仅是增添了一维,在实现的时候嵌套进去就可以了,还是比较容易理解的。
下面看一下实现。 -
更新
void add(int x, int y, int d){ //x,y分别是一维和二维,d是要加上或者减去的数 int yy = y; while(x<=MAX){ y = yy; while(y<=MAX){ tree[x][y] += d; y += lowbit(y); } x += lowbit(x); }
建立初始的树状数组,实质上就是不断调用 add() 函数,从而完成初始化。
-
查询
int sum(int x, int y){ int sum = 0, yy = y; while(x>0){ y = yy; while(y>0){ sum += tree[x][y]; y -= lowbit(y); } x -= lowbit(x); } return sum; }
二维树状数组的查询,查询的是一个子矩阵,如下图:
sun(5, 5) 是橙色框中的子矩阵的元素之和
-
更高维度的树状数组同二维树状数组的原理是一样的,在实现时,只是层次嵌套的问题。