01-Trie 上状压 dp
首先可以发现,如果两个数的二进制前面 $B$ 位相等,那么这 $B$ 位数无论 $x$ 为多少都无法产生贡献。
然后还可以发现,第一个不相等的位可以确定两个数的大小。
考虑把 $a$ 序列插到 01-Trie 里面,这样从顶点到某个点的路径代表这棵子树中的值前面的位数都相等,接下来只需考虑这棵子树里的贡献就好了。
先假设 $x=0$,此时 Trie 里面的所有点都是原来的值。
考虑如果从一个点的 $0$ 子树选一个数 $p$,$1$ 子树选一个数 $q$,很显然 $p<q$,答案是 $q-p$。所以想要 $p$ 尽量大,$q$ 尽量小。
而如果两个数都在同一棵子树中,由于包括这一位前面位数相等,所以直接递推到子树考虑即可。
所以可以记 $mn{u},mx{u},rs{u}$ 分别表示 $u$ 子树能取到的最小最大值和最小差值就可以转移了。
再考虑把 $x$ 的限制加上,实际上相当于给某些曾的儿子进行了翻转,而对某一个子树 $u$ 的答案的影响仅限于 $u$ 以下的层。
所以每一个节点只需要记录它子树内的每一种翻转情况的答案即可。
可以发现 Trie 上深度为 $i$ 的点最多有 $2^i$ 个,而状态数最多有 $2^{n-i}$ 个,每一层乘起来刚好就是 $2^n$,所以直接搞就行了。
时空复杂度 $O(k2^k)$,有点费空间。
代码:
1 |
|

