[每日 E] Kevin and And
思路
有两个集合 \(A\) 和 \(B\)
你可以做至多 \(k\) 次操作,每次选择 \(a_i \in A, b_j \in B\) 并令 \(a_i \gets a_i \& b_j\)
问操作结束后 \(A\) 所有数之和的最小值
因为多操作一定不劣, 所以我们直接钦定操作 \(k\) 次
首先, 如果令每次操作的贡献为 \(val_i\) , 最终答案为 \(ans = \sum_{i = 1}^{n} a_i - \sum_{i = 1}^{k} {val}_i\)
进一步的, 我们把贡献分类, 修改定义, 对于数 \(a_i\) 的操作的贡献我们记为 \(val_i\)
最终答案为 \(ans = \sum_{i = 1}^{n} a_i - \sum_{i = 1}^{n} {val}_i\)
再一次修改贡献, 我们令 \(val_{i, j}\) 表示对于数 \(i\) 进行 \(j\) 次操作的最优贡献
考虑到 \(m\) 很小, 直接枚举所有状态即可 \(\mathcal{O} (n 2^m)\) 计算出 \(val\) 数组
这个时候容易想到 \(\rm{dp}\) , 可惜复杂度趋势了
考虑一个性质
即 \(val_i\) 这一函数具有凸性
给出官方题解对其的证明, 接下来用 \(g(x)\) 表示 \(vai_i(x)\)
引理:函数 \(g\) 是凸的,即对于所有 \(i\) (\(1 \leq i < m\)),不等式 \(2g(i) \leq g(i-1) + g(i+1)\) 成立。
证明:设 \(f(S)\) 是与 \(g(i-1)\) 最小值对应的值,\(f(T)\) 是与 \(g(i+1)\) 最小值对应的值。假设第 \(w\) 位是 \(f(S)\) 和 \(f(T)\) 不同的最高位。
我们总是能找到一个操作 \(y \in T \setminus S\),将 \(g(i-1)\) 中的第 \(w\) 位变为 \(0\)。在这种情况下,我们有:
\[g(i - 1) - f(S \cup \{y\}) \geq 2^w. \]此外,由于 \(f(S \cup \{y\})\) 和 \(g(i+1)\) 不同的最高位不大于 \(w-1\),我们有:
\[f(S \cup \{y\}) - g(i + 1) \leq 2^w. \]将这两个不等式结合得到:
\[2 g(i) \leq 2 f(S \cup \{y\}) \leq g(i - 1) + g(i + 1), \]从而证明了 \(g\) 的凸性。
由上, 你可以知道, 如果我们直接对 \(\varphi\) 用大根堆维护最大值, 然后贪心的选取最大值即可, 因为上面提到的那个性质, 这个贪心显然是成立的
相当于用堆维护指针所指的位置的最大值, 然后如果使用了这一位, 就把指针后移
总结
用堆维护的一类问题, 多半是要做到每个数只有 \(1\) 次插入删除
一类贪心模拟操作的套路题, 用堆维护, 一般有两个要求
- 操作贡献具有单调性
- 操作贡献差值具有单调性


浙公网安备 33010602011771号