题解:P15245 [WC2026] 二进制

耗时 1.5 h。写一下做题时的思路,证明可以参考 官方题解,做法和这个类似。(以下二进制规定高位在后,低位在前)

第一眼想到 LCA 相关的东西,又想到暴力枚举最终得到哪个数,发现没什么前途。

性质 B

然后思考性质 B:\(y=x\cdot 2^k+t,t\in[0,2^k)\),也就是 \(x\) 左移 \(k\) 位后可以和 \(y\) 的某个后缀相等。

于是很自然地想到一个策略,\(x\) 左移 \(k\) 位,然后在左移的过程中顺便补全 \(x\) 的前面部分,使 \(x=y\),操作次数为 \(k+\mathrm{popcnt}(y\bmod 2^{k})\)

然后找到一个 hack,发现这样不是最优的:\(y=(11111)_2,x=(11)_2\)。按照上述策略输出为 \(6\),但答案为 \(5\)\(x,y\) 分别 \(+1\)\(x\) 再左移三位。

我们把这个操作看作是:

  • \(x\) 先变成 \(11000\)
  • 按照原先策略,\(x\) 需要在前面补三个 \(1\)
  • 但我们让 \(y\to y+1\),清空了前面三个 \(1\),相当于 \(11111\to 11000 + 01000\),此时 \(x\) 只需补上这个 \(01000\) 就能和 \(y\) 相等了。

重新调整策略,选定 \(z\in[0,2^k)\),先使 \(y\to y+z\),然后 \(x\) 左移 \(k\) 位,\(x\) 补上 \(\mathrm{popcnt}(y\bmod 2^k+z)\)\(1\),总操作次数是 \(k+z+\mathrm{popcnt}(y\bmod 2^k+z)\)

于是我们可以枚举 \(i=0,1,\cdots,k-1\),表示把 \(y\)\(0\sim i\) 位全部加成 \(0\),再往 \(i+1\) 位进 \(1\),复杂度是 \(O(T\log V)\) 的。

发现 \(z\) 超过 \(O(\log V)\) 一定不优,于是 \(i\in[0,\min(6,k))\),可以做到 \(O(T\log\log V)\)

于是就过了性质 B。

\(96\) pts

我的想法是把一般情况也转换成性质 B。

\(x\cdot 2^k\le y<x\cdot 2^{k+1}\)\(y=x\cdot 2^k+t\)

瞪一下样例,大胆猜测 \(y\to 2y\) 是没用的,于是要转换成 B,只有以下两种方式:

  1. \(x\to x+2^k\cdot\lfloor\frac{t}{2^k}\rfloor\),这样一来,\(t\) 满足 \(t\in[0,2^k)\),就可以套用性质 B。

  2. \(y\to x\cdot 2^{k+1}\)\(k\to k+1\)

\(100\) pts

上面做法过不了的原因是,__builtin_popcount 也有复杂度(我不知道咋算)。

或者直接分块预处理出 \(\mathrm{popcnt}\) 可能也可以过。

我的做法是,预处理 \(i\in[0,5)\) 的答案。由于 \(i=5\) 时会往第 \(6\) 位进位,这时若 \(k>6\),则答案依赖于 \(y\bmod 2^k\) 的具体值,这种情况特殊处理即可。

Code

posted @ 2026-02-13 10:38  chenwenmo  阅读(17)  评论(0)    收藏  举报