CF2131G 题解

调了一个下午,发现 long long 存不下 \(2^{63}\)


我们考虑如何删掉一个数。以 \(4\) 举例:

\[\{ 4 \} \to \{ 1, 2, 3 \} \to \{ 2, 3 \} \to \{ 1, 3 \} \to \{ 3 \} \to \{ 1, 2 \} \to \{ 2 \} \to \{ 1 \} \to \varnothing \]

状压一下(第 \(i\) 位是 \(1\) 当且仅当 \(i + 1 \in S\)):

\[1000 \to 111 \to 110 \to 101 \to 100 \to 011 \to 010 \to 001 \to 000 \]

于是需要 \(8\) 步,得分会乘 \(\prod \limits_{i = 1}^8 (\log_2(\operatorname{lowbit}(i)) + 1)\)。总结出规律:想删掉 \(n\),需要 \(2^{n - 1}\) 步,得分会乘 \(\prod \limits_{i = 1}^{2^{n - 1}} (\log_2(\operatorname{lowbit}(i)) + 1)\)

考虑如何快速计算 \(f(n) = \prod \limits_{i = 1}^n (\log_2(\operatorname{lowbit}(i)) + 1)\)。把 \(\log_2(\operatorname{lowbit}(i)) + 1\) 写出来:\(1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, \cdots\),发现这个数列的第 \([1, 2^i - 1]\) 项一定对称,于是考虑分治。

  • \(n = 2^m - 1\)\(f(n) = m \cdot f^2 \left( 2^{m - 1} - 1 \right) = \lceil \log_2(n) \rceil \cdot f^2 \left( \left \lfloor \dfrac{n}{2} \right \rfloor \right)\)

  • 否则:设 \(n = 2^a + b\),其中 \(b < 2^a\),则 \(f(n) = f ( 2^a - 1 ) \cdot (a + 1) \cdot f(b)\)

    Q. 如何求 \(2^a\)

    A. \(2^a\) 实际上就是 \(n\) 的最高位。

    i64 highbit(i64 x)
    {
        x |= x >> 1;
        x |= x >> 2;
        x |= x >> 4;
        x |= x >> 8;
        x |= x >> 16;
        x |= x >> 32;
        return x - (x >> 1);
    }
    

回到题目,我们首先把 \(s\) 排序,然后从小到大删。

如果剩余步数足够删完 \(s_i\),那就把答案乘上 \(f(2^{s_i - 1})\)

如果不够,设还剩 \(k'\) 步,\(x = 2^{s_i - 1}\),则要把答案乘上 \(\prod \limits_{i = x - k' + 1}^x (\log_2(\operatorname{lowbit}(i)) + 1)\)。根据这个数列的对称性,我们可以把这个式子变成 \(s_i \prod \limits_{i = 1}^{k' - 1} (\log_2(\operatorname{lowbit}(i)) + 1) = s_i \cdot f(k' - 1)\)

时间复杂度:\(O(n \log V)\),其中 \(V\) 为值域。代码

posted @ 2025-09-07 13:03  David9006  阅读(9)  评论(0)    收藏  举报