树状数组 推广

来源:互联网 发布:python 企业级架构 编辑:程序博客网 时间:2024/05/18 09:57

大家都知道普通的树状数组的实现,
大致是这样的:
这里写图片描述
节点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
原创粉丝点击