训练记录PART8 2019.2.14~

友情提醒:大部分题选自opentrains,以后有训练需要的同学慎重查看。

T135-NAIPC 2018 B

  题意:给出一个 \(N\) 个点 \(M\) 条边的图。问有多少种选取点集 \(V\) 的方法,满足 \(V\) 的导出子图是一个团,而 \(N-V\) 的导出子图是一个独立集。\(N,M \leq 2 \times 10^5\)
  题解:看不懂 claris题解 里的神奇做法。
  我们每次考虑所有点中度数最大的点 \(O\),考虑它在哪个点集里。假设它在 \(N-V\),那么所有和 \(O\) 有边的点 \(P_1,P_2,\dots,P_k\) 必须在 \(V\) 中(当然,它们两两之间也必须有边),此时 \(P_i\) 的度数至少是 \(k\) 了。因为 \(O\) 的度数只有 \(k\),所以 \(V\) 中必须恰好是 \(P_{1 \sim k}\) 这些点。我们只需支持快速判断 \(P_{1 \sim k}\) 是否是一个团,以及 \(N-V\) 是否是一个独立集。假设它在 \(V\),那么之前和 \(O\) 没有边的那些点必然在 \(N-V\) 之中,而且它们对于后续的判断已经没有用处了,我们可以直接从图上删掉这些点。即:我们只需考虑 \(P_{1 \sim k}\) 这个点集,哪些划到 \(V\) 里,那些划到 \(N-V\) 里。变成了一个子问题,递归下去即可。
  找 \(P_{1 \sim k}\) 时复杂度是算在边上的;所以每层递归里,常数次枚举 \(P_{1 \sum k}\) 复杂度依然是线性的。如何判断 \(P\) 是一个团呢?我们只需实时维护每个点的度数。每次找到 \(P\) 后,我们暴力枚举目前考虑的点集里除掉 \(P\) 后的点集 \(Q\) (这些都是不和 \(O\) 有边的点)。这些点永远也没有用处了,我们可以枚举它们的所有边,将出点度数减一,并删除这些点。均摊复杂度 \(O(N+M)\),实现时有很多细节。

T135-NAIPC 2018 C

  题意:有 \(N(\ leq 16)\) 个灯泡,给出它们的初始亮暗的情况。每秒钟你可以什么都不干,或者至多拨动一个开关 \(i\):假设现在时间是 \(t\),第 \(t\)\(i\) 状态翻转,第 \(t+1\)\(i+1\) 状态翻转……一直到灯泡序列末尾后影响停止。问最早什么时候灯泡能全亮的景象。
  题解:如果直接状压,很难处理翻转的延续效果,强行记状态会达到 \(O(2^N \times 2^N)\) 的规模。不妨假设枚举最终时刻 \(T\)(显然 \(T \leq N\)),这样子就可以快速 DP 了。设 \(f_{i,S}\) 表示到了第 \(i\) 秒钟,灯泡亮暗状态是 \(S\) 的情况能否达到。转移时如果枚举拨动开关 \(i\),我们可以根据 \(T\) 算出它的翻转区间,直接集体翻转即可。总复杂度是 \(O(2^N \times N^3)\)。因为 \(T\) 远远不到 \(N\),且常数很小,可以通过此题。
  观察最优解的翻转情况,我们可以得到一个结论:存在一种最优解,它的所有翻转区间的长度都不同(因为每一秒才能拨动一次,持续长度不断递减)。显然,最后的答案就是最长区间的长度。那么可以设 \(f_{i,S}\) 表示到了时间 \(i\),状态 \(S\) 是否能达到。每次枚举等于当前时间 \(i\) 的长度区间来异或,复杂度 \(O(2^N \times N^2)\)

猜你喜欢

转载自www.cnblogs.com/jiangshibiao/p/10462309.html