树状数组的单点更新,区间查询。

基本的数组数组概念,树状数组利用其特殊的位置可以用二进制达到log级别的更新,如下图
示意图

核心代码

int sum(int i){
    int s = 0;
    while(i > 0){
        s += dat[i];
        i -= i&-i;
    }
    return s;
}
void add(int i,int x){
    while(i <= n){
        dat[i] += x;
        i += i&-i;
    }
}

lowbit的作用是求出最低位的那个1,为什么这样可以求出来呢,是因为计算机中是采用补码的方式来存储数值型数据,所以负数的补码是原码取反再+1,一个二进制数取反后,后面如果现第一个1,那么这位将变为0,而他后面的0都取反为1,所以再+1,就是这位变为1,而他后面的都变为0,这样再与原来的数字进行与运算就能获得
这里有一个特殊的操作lowbit(x) = x&-x,通过这个操作我们就可以访问到上一层或则下一层,当我们需要去求前3项的和时,只需要向下执行i -= lowbit(i)的操作就行了,从图中你就会发现这正好就是前两项的和再加上第三个和,确实就是如此的巧妙,同理我们更新的时候就是不断向上去更新。因为这里就利用了二进制的巧妙,比如当我们在2的乘法的位置的数就就是前面全部的和然后它再减去它的lowbit就是0,因为他只有最高位是1,而非2的乘方的位置,他会一直向下去寻找,知道找到第一个乘方的位置,加起来就刚好是前n项的和。希望你能明白。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值