ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

树状数组

2021-11-07 16:02:57  阅读:174  来源: 互联网

标签:前缀 树状 int lowbit 数组 BIT


树状数组又称二叉索引树(Binary Indexed Tree),1994年由Fenwick发明。多用于高效计算数列的前缀和区间和。可以以\(O(log n)\)的时间得到任意前缀和,并且可以在\(O(log n)\)时间内修改单点的值。其空间复杂度是\(O(n)\)。

思想

我们有一个数组 A,对它进行如下构造,构造出一个如下的树状数组 C。

image-20211107143746874

其中C[i]等于与它连线的元素相加:

C1 = A1;
C2 = A1+A2;
C3 = A3;
C4 = A1+A2+A3+A4;
......

我们定义一个函数 lowbit(i) :表示二进制数 i 的低位第一个非零1代表的数。如 2(0010) 的 lowbit 为 \(10_{2}\);3(0011) 的 lowbit 为 \(1_{2}\);8(1000) 的 lowbit 为 \(1000_{2}\)。

我们可以发现,C[i] 是由一些连续的A[i]、A[i-1]、A[i-2]...相加得来的。具体是多少个连续的A[j]相加呢,就是数组C的下标的lowbit个,比如:C2 = A1+A2,C2的lowbit是2;C3 = A3,C3的lowbit是1; C4 = A1+...+A4,C4的lowbit是4。因此可以得到如下的关系式:

\[C[i] = \sum_{j=i-lowbit(i)+1}^{i}{A[j]} \]

有了关系式我们就可以构造出树状数组C了。

这样在求前缀和S[i]时,我们不用去求A[1]+...+A[i],而是可以通过数组C来求。

比如求S[4],即是C[4];S[6] = C[6] + C[4];S[8] = C[8]。可以看到,这大大降低了求前缀和的复杂度。

树状数组的思想就是:所有的整数都可以表示成2的幂和,我们也可以把一串序列表示成一系列子序列的和。采用这个想法,我们可将一个前缀和划分成多个子序列的和,而划分的方法与二分非常相似。

基本方法

变量说明:原数组 A,树状数组 BIT

注意,通常我们会让 A[0]、BIT[0]都为空,从下标1开始存放数据,这会让编程更方便。因此下面给出的方法都是这样假定的。具体使用时你可以根据需要做一些小心的下标变换,改成从下标0开始

lowbit

在计算机中计算 lowbit 有非常高效的位运算:lowbit(x) = x & -x

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

初始化 BIT

void init(){
  for (int i = 1; i <= A.length; i++) {
    BIT[i] = A[i];
    for (int j = i - 1; j > i - lowbit(i); j -= lowbit(j)){
      BIT[i] += BIT[j];
    }
  }
}

单点修改

// 将A[i]的值增加 delta
void add(int i,int delta){
  for(int j=i; j<=A.length; j+=lowbit(j))
    BIT[j] += delta;
}

求前缀和

// 求下标 k 的前缀和
int sum(int k){
  int ans=0;
  for(int i=k; i>0; i-=lowbit(i))
    ans+=BIT[i];
  return ans;
}

参考:https://zh.wikipedia.org/wiki/树状数组

标签:前缀,树状,int,lowbit,数组,BIT
来源: https://www.cnblogs.com/cpcpp/p/15520167.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有