数据结构-树状数组学习笔记

🌳 树状数组 学习笔记

树状数组究竟是个什么东西呢?

形态结构就是前缀和融合,创造出来的"可以动态加点前缀和" ✨

通过按位存储的方式,使得前缀和可以二分操作

具体的,是把区间信息像前缀和一样维护出来(不过利用了二进制),然后,让指针站在 0 起点,按照二进制的指令,跳到每个区间,进行操作 🎯


1. 存储方式 📦

每个点管一小段区间,lowbit(二进制下最低位)决定管多宽。

比如:

  • \(c[4]\)(二进制 100,末尾有 2 个 0,所以 lowbit(4)=4
    管的是 \(a[1] + a[2] + a[3] + a[4]\)
  • \(c[6]\)(二进制 110,末尾有 1 个 0,所以 lowbit(6)=2
    管的是 \(a[5] + a[6]\)
int lowbit(int x){ return x & -x; }   // lowbit代码

🔑 重点: lowbit 决定了每个节点覆盖的区间长度,也是跳转的步长。


2. 区间加操作 ➕

记住代码里 xval 各自出现 2 次i 每次向上跳 lowbit(i),全加 c[i] += val

void add(int x,int val){for(int i=x;i<=n;i+=lowbit(i)) c[i]+=val;}
//  ↑                  ↑
//  x出现第1次         x出现第2次
//  val出现第1次       val出现第2次

🔑 重点:x 开始,不断向上更新父节点,直到超过 n


3. 区间求和操作 🔢

i = x 之后每次往下跳 lowbit(i) 就行,累计 s += c[i]

int sum(int x){int s=0;for(int i=x;i>0;i-=lowbit(i)) s+=c[i];return s;}

🔑 重点:x 开始,不断向左下跳,累加区间和,直到 i = 0


4. 变式 🔄

未完待续

变式 核心思想 代表题目
单点修改 + 区间查询 维护原数组 P3374
区间修改 + 单点查询 维护差分数组 P3368
区间修改 + 区间查询 维护两个树状数组
值域树状数组 把数值当下标,求第k小/逆序对 P1908、P1168
树状数组上二分 倍增找第k小

一句话总结: 树状数组 = 每个点管一段小区间,lowbit 决定管多宽。sum 从高到低,add 从低往高跳。💪

posted @ 2026-08-07 16:37  敛才有道  阅读(2)  评论(0)    收藏  举报