关于树状数组

树状数组的核心在于对一段区间的修改和查询,巧妙地把数组用一颗树表示,从而降低了对数组的修改和查询的复杂度。

首先引入lowbit()

int lowbit(x)

{
  return x & (-x);
}

 

如:

x =1: 1 &-1

            0000 0001 & 1111 1111 = 1

x = 6:   6  &  -6  

            0000 0110 & 1111 1010 = 2

总结一下就是:

求出某个数二进制表示从右起出现的第一个1及后面的0一起表示的二进制数,如6的二进制表示为110,向左数第一个为0,第二个为1,故Lowbit(6) = 10(2) = 2(10)。

现在看树状数组的图:

我们可以发现没个子节点的父亲节点的下标就是该节点的下标 i + lowbit(i),利用这个特性,我们就可以得到对树状数组的两个操作函数

更新节点:

void Add(int x, int y)
{
    for(int i = x;i <= n;i += lowbit(i))
    {
        c[i] += y;
    }
}

查询区间:

int Sum(int x)
{
    int ans = 0;
    for(int i = x;i > 0;i -= lowbit(i))
    {
        ans += c[i];
    }
    return ans;
}

用这两个函数就可以对树状数组进行更新和查询操作。

 

转载于:https://www.cnblogs.com/ScaleCX/p/9308125.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值