数据结构-树状数组学习笔记
🌳 树状数组 学习笔记
树状数组究竟是个什么东西呢?
形态结构就是前缀和与树融合,创造出来的"可以动态加点前缀和" ✨
通过按位存储的方式,使得前缀和可以二分操作。
具体的,是把区间信息像前缀和一样维护出来(不过利用了二进制),然后,让指针站在 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. 区间加操作 ➕
记住代码里 x、val 各自出现 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从低往高跳。💪

浙公网安备 33010602011771号