树状数组 推广

大家都知道普通的树状数组的实现,
大致是这样的:
这里写图片描述
节点k,统计的叶子范围为: [klowbit(k)+1,k]
而每一个节点都只记录左儿子的信息,
我们能够查询的也就只是 [1,n] 的信息。
通常使用树状数组维护前缀和,但有时也能用来做一些看似只有线段树才能实现的功能。

区间更新

我们用前缀和维护每个位置的增加的值。
S[i] 表示 [i,n] 位置上的数都增加 S[i] 的值。
那么如果对 [l,r] 增加d,就 S[l]+d,S[r+1]d
求和的话,设原数组为 A ,那么对[l,r]求和,
答案就是:

Ans=i=lr(A[i]+(ri+1)S[i])=i=lrA[i]+i=lr(rS[i]iS[i]+S[i])=i=lrA[i]+(r+1)i=lrS[i]i=lriS[i]

而现在上面的 ri=lA[i],ri=lS[i],ri=liS[i] 都可以维护。
后面两个由于都只有单点的修改,即可使用树状数组。( iS[i] 将要增加的值乘以i就行了)
下面再给出两个公式:
i节点的左儿子编号为: ilowbit(i)2
i节点的右儿子编号为: i+lowbit(i)2
有了这两个公式,能够很方便地得到一个节点地左右儿子,
便可以类似线段树地方式实现很多功能。
未完待续。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值