用 lowbit 把前缀和拆成 log n 段,支持 O(log n) 的单点改与区间查。
lowbit(x)=x&-x 在干什么;求前缀和 query(7) 时,下标从 7 开始不断 减 lowbit:7 → 6 → 4。每次把该下标的树状数组值加起来。点按钮逐步看。
| 写法 | 含义 |
|---|---|
lowbit(x)=x&-x | 取出 x 二进制里最低位的 1(如 lowbit(6)=2) |
add(i, v) | 单点加:从 i 开始向上(i+=lowbit(i))更新所有覆盖区间 |
query(i) | 前缀和:从 i 开始向下(i-=lowbit(i))累加 |
query(r)-query(l-1) | 区间 [l, r] 的和 |
int 而前缀和可能超 int,记得开 long long。要给 [l, r] 全部加 v、再问某个点的值,就对差分数组 d[l]+=v; d[r+1]-=v;,用树状数组维护 d 的前缀和即可。本质是「单点改」和「区间查」互换。
lowbit 只保留最低位的 1,好比十进制里只看个位——6 的个位是 6、4 的个位是 4,查询时每次「退到个位为 0 的下一档」。这和银行「整元整角」记账、或电脑里按 2 的幂分块管理内存是一回事:用结构化的分组,把 O(n) 的工作摊薄成 O(log n)。
lowbit(6) 的值为多少?为什么 add 要向上(i+=lowbit)而 query 向下(i-=lowbit)?