AT_pakencamp_2018_day2_g

可能更好的阅读体验

第一篇黑题题解,但是感觉会被降紫,毕竟我都会,降紫哥肯定直接就秒了。

这个做法在数组开小的情况下能过模拟赛数据(\(M-N\) 模拟赛题更大),不懂。

首先注意到 \(M-N\le3\),也就是说给出的图是在树上加了不超过 4 条边。于是先任意求出一个生成树,再考虑另外的至多 4 个限制。

这个限制很难算,考虑容斥。设 \(S\) 中限制均不满足且树边均满足的方案数为 \(cal(S)\),则答案为 \(\sum_S (-1)^{\lvert S\rvert}cal(S)\)

可是由于限制的点之间的路径不是链,所以 \(cal(S)\) 还是很难算。但是因为至多只有 8 个点,所以虚树上至多只有 15 个点,于是考虑建虚树并提前算好边的实际长度。

现在我们先解决这样一个问题:给定链的长度和链两端颜色是否相同,求链的染色方案数。设 \(f_{i,0/1}\)为“长度为 \(i\) 的链,倒数第二个点的颜色与最后一个是否相同”时给链中间点的染色方案数,显然有 \(f_{i,0}=(k-1)f_{i-1,1}+(k-2)f_{i-1,0},f_{i,1}=f_{i-1,0}\),于是可以 \(O(n)\) 预处理。

考虑状压 DP,设 \(f_{S,i}\) 为给 \(S\) 中点染了 \(i\) 种颜色后,已确定部分(虚树上有至少一个端点在 \(S\) 中的边构成的集合)的染色方案数。

转移时枚举下一个颜色所对应的点集 \(S'\)。为了满足限制,记 \(inp_i\) 为某一端点是 \(i\) 的限制(也是虚树上的一些边)构成的集合,那么只有 \(\forall x\in S',inp_x\in S'\) 才合法。

转移系数即为 \(S'\) 内部虚树边的贡献以及 \(S'\)\(\overline {S\cup S'}\) 之间虚树边的贡献再乘上颜色的选择方案,直接使用之前预处理的结果。

最终答案即为 \(\sum \frac{f_{U,i}}{i!}+(k-1)^{n-sz}\)(颜色的排列顺序会被算入所以要除掉,\(sz\) 表示不在虚树上的点数),预处理阶乘的逆元即可。令 \(P=M-N+1\),时间复杂度约为 \(O(82^PP^2)\)。(选一个限制可视为使虚树增加 \(4\) 个点,所以约有 \(3^4+1=82\) 种情况)

注意到一个限制中的两个点只会同时选,所以在状态里可以压到一起,时间复杂度约为 \(O(28^PP^2)\),已经能过了。

注意到转移系数只和 \(S,S'\) 有关,预处理即可,时间复杂度约为 \(O(28^PP)\)

作者数学不好,如果你能把复杂度算的更准确欢迎留言。

整理后的代码提交记录

upd1:不容斥直接算的话不能压缩状态,所以时间复杂度约为 \(O(81^PP)\)

posted @ 2025-02-18 18:06  ax_by_c  阅读(16)  评论(0)    收藏  举报