树状数组

树状数组

时间复杂度为Olgn

一般讲到树状数组都会少不了下面这个图:


据图可知:  c1=a1c2=a1+a2c3=a3c4=a1+a2+a3+a4c5=a5c6=a5+a6c7=a7c8=a1+a2+a3+a4+a5+a6+a7+a8c9=a9c10=a9+a10c11=a11........c16=a1+a2+a3+a4+a5+.......+a16

分析上面的几组式子可知,当 i为奇数时,ci=ai;当 i为偶数时,就要看 i的因子中最多有二的多少次幂,例如,6的因子中有 2的一次幂,等于 2,所以 c6=a5+a6(由六向前数两个数的和),4的因子中有 2的两次幂,等于 4,所以 c4=a1+a2+a3+a4(由四向前数四个数的和)。

  1. 有公式:cn=a(n-a^k+1)+.........+an(其中k n的二进制表示中从右往左数的 0的个数)。

a^k

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

  1. 求数组的和的算法如下:

  1. 首先,令sum=0,转向第二步;

  2. 接下来判断,如果 n>0的话,就令sum=sum+cn转向第三步,否则的话,终止算法,返回sum 的值;

  3. n=n –lowbit(n)(将n的二进制表示的最后一个零删掉),回第二步。

码实现:

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

  1. 当数组中的元素有变更时,树状数组就发挥它的优势了,算法如下(修改为给某个节点i 加上x ):

  1. i<=n时,执行下一步;否则的话,算法结束;

  2. ci=ci+xi=i+lowbit(i)(在i 的二进制表示的最后加零),返回第一步。

代码实现:

void change(int i, int x){
    while (i <= MAX) {
        c[i] += x;
        i = i + lowbit(i);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值