线段树 + 压位.
- 可以用线段树维护 $x$ 的每个二进制位,一次加/减法可以拆成 $\log$ 次给某一位 $\pm 1$.
- 假设给第 $p$ 位 $+1$ ,就向高位找到第一个为 $0$ 的位置 $q$ ,将位置 $q$ 改为 $1$ , $p\sim q-1$ 改为 $0$ .
- 假设给第 $p$ 位 $-1$ ,就向高位找到第一个为 $1$ 的位置 $q$ ,将位置 $q$ 改为 $0$ , $p\sim q-1$ 改为 $1$ .
- 这样直接做是 $O(n\cdot \log^2n)$ 的,比较慢.因为只维护 $0/1$ 信息,所以一个比较自然的想法是压位. $b\le 30n$ ,为了方便,将 $30$ 位压在一个 $int$ 里面,这样每次操作只用拆成 $2$ 位.
- 线段树的第 $i$ 个位置维护了二进制位 $(i-1)\times 30\sim i\times 30-1$ 这些位置上的信息.时间复杂度 $O(n\cdot \log n)$.
细节巨多,巨烦.调了两节课.
1 |
|