树状数组 (数据结构)

扫盲篇:

在线的数据结构,支持随时修改某个元素的值,复杂度也为log级别。

假设A[]数组为存储原来的值得数组,C[]为树状数组。

我们定义:C[i] = A[i - 2^k + 1] + ..... + A[i]  其中k为i用二进制表示时的末尾0的个数。例如:i= 10100,则k = 2,i = 11000,则k = 3;(i为二进制)

求解2^k的值得方法:

1.int lowbit(int x){  return x&(x^(x–1));  }

2(利用机器的补码原理) int lowbit(int x){  return x&(-x);

http://img.blog.csdn.net/20130820135411406?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGpkNDMwNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

第一个函数;

int lowbit(int x)
{
    return x&(-x);
}

如果是x+=x&(-x);就是得到的改点的父节点的值

如果是x+=x&(-x);就是得到的改点的父节点的值

第二个函数
void update(int x,int num)
{
    while(x<=N)
     {
         d[x]+=num;
         x+=lowbit(x);
     }
}

第三个函数
int getSum(int x)
{
    int s=0;
    while(x>0)
     {
         s+=d[x];
         x-=lowbit(x);
     }
    return s;
}

拓展到二维:

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(j))
            ret += c[i][j];
    return ret;
}
void add(int x,int y,int val)
{
    for(int i = x;i <= n;i += lowbit(i))
        for(int j = y;j <= n;j += lowbit(j))
            c[i][j] += val;
}

原文地址:https://www.cnblogs.com/henserlinda/p/5187679.html