专题训练 - 构造 III
[CF1451E2] Bitwise Queries (Hard Version)
首先使用 次操作询问出 ,然后我们只需要求出某一个 就可以求出整个序列了。
由于 x\or y=x\oplus y\oplus(x\and y),事实上此时已经可以求出任意两个 的异或和,所以我们可以只考虑 \and。
下面假设你询问了 a_i\and a_j,下一次再询问,不可能是另外两个完全不同的位置。这是因为目前为止我们已知的所有信息都是对称的,对称的话就势必不能解出唯一解,除非你解出来的两个解是相等的,显然数据并不能保证这一点。
不妨设已知 a_i\and a_j 与 a_j\and a_k,其中 两两不同,接下来我们考虑某个二进制位的情况。
- 若 a_i\and a_j=1 或者 a_j\and a_k=1,那么 。
- 否则,若 或者 ,那么 。
- 否则,此时我们可以推出 ,枚举不难发现只能是 或 。
我们会发现,最后的情况是无法确定出来到底是哪一种的。如果是 Easy Version 允许询问 次,只要询问 a_i\and a_k 就好了。
那么,我们如何省掉这一次询问?这就必然和题目保证的特殊数据范围有关系了。
不难发现取值范围 有 个不同的数,所以如果 两两不同,那么它们一定是 的一个排列。
在考虑这种特殊的情况之前,我们先来看如果存在两个相同的元素该怎么办。
- 如果存在某个 满足 ,这等价于 ;
- 如果存在某对 满足 ,这等价于 。
如果存在这样的情况,我们只需要问这两个位置的 \and 或者 \or,就可以求出这个位置的取值,然后解出每一个值了。
好,下面再看 组成 的排列这一情况。由于 是 的幂,所以任意两个 的数异或起来仍然在 中,因此 一定是 的一个排列(如果有 是上一种情况)。
那么就必然存在一个 使得 。这有什么特殊的?因为这两个数异或起来二进制全 ,那么它们不可能有两个位置都是 ,于是 a_1\and a_k=0,这就可以帮我们省掉一次询问。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 喵喵小窝!