CF2283C 题解
题意简述
从 1 到 n 中选择一些数字,将选中的数字乘 2,使修改后所有数字的异或和不小于原序列按位或的 2 倍。
tag:计数 动态规划
难度cf1250 洛谷普及
思考
设 n 的最高位下标为 d。因为 1 到 n 中包含 2^d,并且低于第 d 位的每一位都能在某个数中出现,所以:
$$1 \mid 2 \mid \cdots \mid n = 2^{d+1}-1 = 111\cdots111_2$$
记这个按位或的结果为 k。
因此,我们需要让最终异或和至少为 2k。由于:
$$2k = 2^{d+2}-2 = 111\cdots110_2$$
所以目标是让最终异或和的第 d+1 位到第 1 位全部为 1,最低位无特殊要求。
贪心
先计算当前异或和 $ans = 1 \oplus 2 \oplus \cdots \oplus n$,然后从高位向低位处理。
假设当前处理第 i+1 位:
如果这一位已经是
1,不需要操作;如果这一位是
0,就选择2^i,将它乘2变成2^{i+1}。
这次操作会使异或和变为:
$$ans’ = ans \oplus 2^i \oplus 2^{i+1}$$
因此只会改变第 i 位和第 i+1 位。当前第 i+1 位会被翻转为 1,而更高位不会受到影响。
继续从高位处理到低位,就能保证已经处理好的高位不会被破坏,最终得到满足条件的异或和。
复杂度
计算初始异或和为 O(n),按位贪心为 O(log n),总复杂度为 O(n)。
代码
1 | #include <bits/stdc++.h> |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Esther 的博客!

