【算法】浅谈树状数组

参考资料

    从0到inf,超详细的树状数组详解


概念

    从名字就不难看出,树状数组就是一个树形的数组,如下图

    

    其中:

    01 02 03 04 为原数组,记为 a 数组

    1 2 3 4 为树状数组,记为 t 数组

    不难发现,

  t[1] = a[1]
  t[2] = t[1] + a[2] = a[1] + a[2]
  t[3] = a[3]
  a[4] = t[2] + t[3] + a[4] = a[1] + a[2] + a[3] + a[4]

    但似乎还是找不到规律,我们尝试将它转换成二进制试试

  t[1]   = a[1]
  t[10]  = a[1] + a[10]
  t[11]  = a[11]
  t[100] = a[1] + a[10] + a[11] + a[100]

    也就是说,从最低位的 1 开始一直加到 1 ,就是 t[i] 的值,即

t[i]=a[i]+a[i2k+2]+a[i2k+1]

    这时引入 lowbit 的概念,它可以计寻找出最低位的 1

lowbit(x)=x&(x1)

    为什么这样就能取到最低位的 1 了呢?

    这里先给出一些基本概念,方便不熟悉的读者观看:二进制的原码、反码、补码

    我们直接以 7 为例:

    7 的二进制为 0111

    -7 的二进制为 1001

    我们又知道 & 表示:如果两个相应的二进制位都为1,则该位的结果值为1,否则为0

    所以 7&(7)=0001,就得出了最低位 1

    怎么将这个结论具有普遍性呢?这里不妨自己尝试一下


实现

    根据上面的分析,我们不难得出查询区间和 (l,r) ,只需利用前缀和即可

  int query(int x){
  	  int sum=0;
	  for(int i=x;i>=1;i-=lowbit(i)) sum+=t[i];
	  return sum;
  }

    更改时,由于树状数组存储的是前缀和,所以只需将它上面的所有父节点同时进行更改即可

  void update(int x,int k){
	  for(int i=x;i<=n;i+=lowbit(i)) t[i]+=k;
  }

    • 单点修改和区间查询

        例题:树状数组1

        更改时只需:update(x,k)

        查询时只需输出:query(r)query(l1)

        将输入的数组看做更改操作即可


    • 区间修改与单点查询

        例题:树状数组2

        这时候我们不能沿用上面那道题的思想了,需要依靠差分的思想来解决

        根据差分数组的特性,我们可以得到以下几个规律:

    差分数组的前缀和可以得到原来数组的值
    将原数组 (l,r) 加上 k 等价于将差分数组第 l 项 +k, 第 r-k

        证明这两个规律可以通过举例子的方式

        这样我们进行区间修改时只需:update(l,k),update(r,k)

        查询时只需输出:query(x)

        注意这里都是对差分数组操作


    • 区间修改和区间查询

        【为什么不试试线段树呢】

        例题:线段树1

        这时我们发现,如果根据上面的思想,区间修改对差分数组操作,区间查询对原数组操作,肯定是不行的。

        我们考虑化简区间查询 (l,r) 的式子:

        i=lrai=t[l]+t[l]+t[l+1]+t[l]+t[l+1]+t[r]

        =n×t[l]+(n1)×t[l+1]+1×t[r]

        =i=1n(ni+1)×t[i]

        =n×i=1nt[i]i=1nt[i]×(i1)

        这样我们可以维护两个数组,一个数组 t[i] 来维护差分,一个数组 pr[i] 维护 t[i]×(i1)

        更改时除了之前的基本操作,还要更新 pr[i],一个简单的乘法分配律可得:pr[i]+=k×(x1);

    查询时按照我们之前化简出来的式子计算即可

posted @   Cloote  阅读(60)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示