二维树状数组

来源:互联网 发布:ios优酷网络连接失败 编辑:程序博客网 时间:2024/05/16 19:15

回顾一维树状数组

这里写图片描述

初始化、求和

c1 = a1;
c2 = a1 + a2;
c3 = a3;
c4 = a1 + a2 + a3 + a4;
c5 = a5;
c6 = a5 + a6;
……
C16 = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + 13 + a14 + a15 + a16;
求和:

int sum (int c[], int n){    int sum = 0;    while(n > 0)    {        sum += c[n];        n -= lowbit(n);    }}

解释一下上面:假设n = 16那么c[16]代表的就是前16项的和,而 16 -= lowbit(16) = 0;所以循环结束。

更改数值

int change (int i, int x, int n) // i表示更改的位置, x表示改为的数。{    while(i <= n)    {        c[i] += x;        i += lowbit(i);    }}

二维树状数组

提出问题

一个由数字构成的大矩阵,能进行两种操作
1) 对矩阵里的某个数加上一个整数(可正可负)
2) 查询某个子矩阵里所有数字的和,要求对每次查询,输出结果。

二维树状数组介绍

一维数组很容易扩展到2维

假设在2维的情况下原始的数据定义为A[][]

那么树状数组就可以定义为C[x][y] = ΣA[i][j]

其中 x - lowbit(x) < i < x; ··········y - lowbit(y) < j < y;

下面我们举个例子:

假设原始的二维数组是:

A[][]={{a11,a12,a13,a14,a15,a16,a17,a18,a19},
{a21,a22,a23,a24,a25,a26,a27,a28,a29},
{a31,a32,a33,a34,a35,a36,a37,a38,a39},
{a41,a42,a43,a44,a45,a46,a47,a48,a49}};

为了好理解我们引入中间数组B[][]

B[1]={a11,a11+a12,a13,a11+a12+a13+a14,a15,a15+a16,…} 这是第一行的一维树状数组
B[2]={a21,a21+a22,a23,a21+a22+a23+a24,a25,a25+a26,…} 这是第二行的一维树状数组
B[3]={a31,a31+a32,a33,a31+a32+a33+a34,a35,a35+a36,…} 这是第三行的一维树状数组
B[4]={a41,a41+a42,a43,a41+a42+a43+a44,a45,a45+a46,…} 这是第四行的一维树状数组

现在举例二维树状数组:

以下内容c[1][1] 表示为c11 以此类推

c11 = a11; c12 = a11 + a12 ; c13 = a13 ; c14 = a11 + a12 + a13 +
a14; c15 = a15………………

c21 = a11 + a21; c22 = a11 + a12 + a22 + a21; c23 = a13 + a23;
C24=a11+a12+a13+a14+a21+a22+a23+a24

c31 = a31; c32= a31 + a32; c33 = a33; c34 = a31 + a32 + a33 + a34;c35
= a35;

c41 = a11 + a21 + a31 + a41; c42 = a11 +a12 + a21 + a22 + a31 + a32 +
a41 + a42;

以上找规律:

我们发现C中的第一个数字表示的是树状数组在纵向上的个数, 第二个数字表示在横向上的个数(也就是一维树状数组)

讲到这二维数组的定义基本讲完,我们返回前面的两道例题

求和

 int Sum(int i, int j) {      int sum = 0;      for(int x = i; x > 0; x -= lowbit(x))       {        for(int y = j; y > 0; y -= lowbit(y))         {            sum += C[x][y];        }      }    return sum; }

和一维的完全一样只是加了一个for循环

改变数值

private void Modify(int i, int j, int n, int m, int delta){         A[i][j]+=delta;       for(int x = i; x< n; x += lowbit(x))        for(int y = j; y < m; y += lowbit(y))        {          C[x][y] += delta;        }}
0 0
原创粉丝点击