20251015

正睿二十连测

2025.11.19 第二遍

https://zhengruioi.com/contest/1996

A

标签 位运算

定义 \(f(x)\) 是一个关于 \(x\) 的表达式,运算符有 \(+,-,*, \&, |, \oplus\), ~。(例如 \(f(x) = (x + 1) * (x \& 6)\))。给定 \(n\)\((x, y)\),问是否存在 \(f\) 使得任意 \(f(x_i) = y_i\)。运算在 \(32\) 位无符号整数意义下进行。

因为他给了很多冗余的运算符,例如 \(-\) 可以用 \(+\) 替代, ~ 可以被 \(\oplus\) 替代。因为没有除法/右移操作,而 \(+,*,\&, |, \oplus\) 这几种有用的运算符只有低位有可能影响高位,而高位不可能影响低位。所以若 \(x_i \% 2^k = x_j \% 2^k\),一定有 \(y_i \% 2^k = y_j \% 2^k\)(忽略更高位),也就得到了一个存在 \(f\)必要条件

实际上这个必要条件也是充分的(随便写个代码跑跑就知道)。证明如下:

\(x_i\) 为奇数和偶数的分开:对于 \(x_i\) 是奇数的部分找到一个 \(f_1(x)\) 满足所有 \(((x_i - 1) / 2, (y_i - 1) / 2)\);对于 \(x_i\) 是偶数的部分找到一个 \(f_0(x)\) 满足所有 \((x_i / 2, y_i / 2)\),则取 \(f(x) = (x \& 1) * (2f_0(x / 2) + b_0) + (1 - (x \& 1)) * (2f_1((x - 1) / 2) + b_1)\) 即可。(\(b_0\) 表示 \(x_i\) 为偶数时,\(y_i\) 是偶数(\(0\))还是奇数(\(1\)))。

现在问题就简化了很多了。枚举 \(k\),然后按 \(x_i \% 2^k\) 排个序判一下随便 \(O(n \log n\log V)\) 过掉。也可以使用基数排序去掉一个 \(log\),即以 \(x_i\) 的第 \(k\) 位为第一关键字,\(x_i \% 2^{k - 1}\) 为第二关键字。

posted @ 2025-10-15 22:55  xiehanrui0817  阅读(13)  评论(0)    收藏  举报