[数据结构-树状数组小结]

树状数组又叫二叉索引树

参考《训练指南》P194

动态求连续区间和,可以动态更新数据,支持以下两种操作:

1、 对某一元素进行更新操作。

2、 查询某一连续区间的元素和。

对于正整数x,我们定义lowbit(x)为“x的二进制表示中最右边的1所表示的值”,例如lowbit(11001100) =100 (这里的11001100、100都是二进制表示),在程序实现中lowbit(x) = x&-x ,原因如下。

x  0000 0000 1100 1100

-x 1111 1111 0011 0100 ---反码加1,称为补码

clip_image002

clip_image004

lowbit(16) = 16

lowbit(8) = 8

lowbit(4) = 4

lowbit(2) = 2

lowbit(1) = 1

A数组下标从1开始。

每一层lowbit值相同,下面构造辅助数组C,C[i] = A[i-lowbit(i)+1] + A[i-lowbit(i)+2] +…..+ A[i]。

C[1]=A[1]

C[2]=A[1]+A[2]

C[3]=A[3]

C[12]=A[9]+A[10]+A[11]+A[12]

C[i]就是以i结尾的白条(看上图)

两个操作的代码如下:

int sum(int x)   //求前缀和,x向左上爬
{
    int ret=0;
    while(x>0)
    {
        ret+=C[x];
        x-=lowbit(x);
    }
    return ret;
}

 

void add(int x,int d)  {  //A[x]加上d,x向右上爬
    while(x<=n) {
        c[x]+=d;
        x+=lowbit(x);
    }
}

 

不难证明,两个操作都是log(n),而预处理操作相当于执行了n次add操作,所以总复杂度是nlog(n)。

完结。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值