https://www.luogu.com.cn/problem/P17024

首先肯定是从高到低确定每一位。

设现在确定了最高的 \(j\) 位 \(s_j\),确定第 \(j + 1\) 位(位号都是从高到低),就是判断所有满足前 \(j\) 位是 \(s_j\) 子集,第 \(j + 1\) 位是 \(0\) 的数之和是否不小于 \(C\)。

但是这个东西不是那么好求,特别是还要依次加入每个数,并每次做一次这个操作。

于是我们考虑对所有询问一起做。

具体的,设 \(solve(j, mask, L, R)\) 表示 \(ans_L \sim ans_R\) 的高 \(j\) 位是 \(mask\),现在决定第 \(j + 1\) 位。显然是存在一个 \(mid\),\(L \sim mid\) 第 \(j + 1\) 位是 \(1\),\(mid + 1 \sim R\) 是 \(0\)。

依次加入 \(L \sim R\) 的元素,在满足高位为 \(mask\) 的情况下产生贡献,就能求出 \(m\)。函数结束后将指针移回 \(L - 1\)。

当然,还需要同时维护 \(1 \sim L - 1\) 的贡献,维护一个数组 \(sum_T\) 表示高位为 \(mask\),低位为 \(T\) 的数的总和。注意到这个树组长度只有 \(2^{k-j}\),所以暴力更新,复杂度是正确的。

时间复杂度:\(O(nk)\)。

想了好久,以为复杂度错的,还是要把想法写下来。怎么又忘了!!