[算法模板]树状数组

[算法模板]树状数组

思路

图片转自:yhf_2015——彻底理解树状数组

使用这个图片就能很快的理解树状数组。

我们可以先根据图片来分解一个十进制数成二次幂。

example:

(15=2^0+14)

(14=2^1+12)

(12=2^2+8)

(8=2^3)

(15=2^0+2^1+2^2+2^3)

图上的每一个白条(包含灰块)就是(c[i])覆盖的范围,而(lowbit(i))就是灰块对应的白条的长度。

example:

(c[12]= sum _{i=9}^{12} a[i])

(lowbit(12)=4)

显然,加上lowbit就可以达到覆盖自己的白条(父节点)。减去lowbit就下一个当前灰块对应白条不包含的,离当前灰块最近的白条。(14->12,12->8,8->0)

实现

总结一下,原数组a和树状数组c大小相等。每个节点的父亲节点为(x+lowbit(x))

修改操作,每次修改给当前位置的c加上权值d。位置p加上lowbit(p),位置(pleq n)

求和操作,每次累加当前位置的c权值。位置p减去lowbit(c),位置(1 leq p)

int lowbit(int x)
{
    return x&(-x);
}
int sum(int x)//查询1-x的值
{
    int ret=0;
    while(x)
    {
        ret+=c[x];
        x-=lowbit(x);
    }
    return ret;
}
void update(int x,int d)//将x的值加上d
{
    while(x<=n)
    {
        c[x]+=d;
        x+=lowbit(x);
    }
}
原文地址:https://www.cnblogs.com/GavinZheng/p/10829834.html