Loading

[每日 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}\) , 可惜复杂度趋势了

考虑一个性质

\[\textrm{Let } \varphi(i, j) = val_{i, j + 1} - val_{i, j} \\ \textrm{Thus } \varphi(i, j) \geq \varphi(i, j + 1) \]

\(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\) 用大根堆维护最大值, 然后贪心的选取最大值即可, 因为上面提到的那个性质, 这个贪心显然是成立的

更形象的, 我们把 \(\varphi\) 表示出来
pEAKyfs.png

相当于用堆维护指针所指的位置的最大值, 然后如果使用了这一位, 就把指针后移

总结

用堆维护的一类问题, 多半是要做到每个数只有 \(1\) 次插入删除

一类贪心模拟操作的套路题, 用堆维护, 一般有两个要求

  • 操作贡献具有单调性
  • 操作贡献差值具有单调性
posted @ 2025-01-21 15:29  Yorg  阅读(57)  评论(0)    收藏  举报