【单选】树状数组维护长度 n = 16 的序列。查询前缀和 sum(11) 与单点修改 add(3, x) 分别需要访问树状数组中多少个下标( )。
树状数组的两次操作都是"沿 lowbit 跳":查询前缀和 sum(i) 是不断 i -= lowbit(i),修改 add(i) 是不断 i += lowbit(i)。把 11 和 3 写成二进制,数一数跳了几次即可。
把两个操作的跳跃方向记反(查询往小跳、修改往大跳);或数 11 时漏了最后一跳到 0 之前的那一步。
本题考查树状数组(BIT)的下标跳跃规律。
记 lowbit(x) = x & (−x),即 x 的二进制中最低位的 1 及其后的 0 组成的数。
| 操作 | 跳跃方向 | 访问的下标序列 |
|---|---|---|
前缀和 sum(i) | 不断 i −= lowbit(i) | i, i−lowbit(i), … 直到 0 |
单点修改 add(i, x) | 不断 i += lowbit(i) | i, i+lowbit(i), … 直到 > n |
11 = 1011₂,lowbit(11) = 1:
访问的下标:11, 10, 8 —— 共 3 个
3 = 11₂,lowbit(3) = 1:
访问的下标:3, 4, 8, 16 —— 共 4 个
sum(11) 访问 3 个下标,add(3, x) 访问 4 个下标,选 A(3 和 4)。
树状数组把区间 [i − lowbit(i) + 1, i] 的信息存在 c[i] 里:
因此本题也可以走捷径:11 的 popcount = 3,直接得 3 次。