Atcoder abc294
https://atcoder.jp/contests/abc294/tasks
Ex - K-Coloring
n点无向图
m 边
点赋值 [1,k] 相邻点值不同的方案数 mod 998244353
n 30
m [0,30]
k 1e9
8s
1024mb
我的思路
m 30, n 30, 想到的30相关的就是2^{30/2} 的meet-in-the-middle, 但没什么具体的想法
方案统计
对于一个具体方案,考虑按照 点的index顺序从小到大交换
例如 1染色x , u染色1, 那么把所有x和1染色的交换成1和x, 那么得到的依然合法
这样 index顺序虫小到大 染色c个的方案数 f(c)
ans = sum f(c) A(Permutation)(k,c)
1 | dfs(u, cntcolor){ |
感觉复杂度会爆炸?吧?
不同难搞,要不然就是反过来容斥 相同
属性i = 边i连的两点颜色相同
ans = sum (-1)^count(属性…) g(属性…)
这个问题就是 $2^{30}$太大, 需要拆分
右侧的g()=k^{未连通块个数}
题解
独立集 indepenedent set: 顶点集合,集合中顶点两两不相邻
如果$n$比较小
$s(i) =$ 恰好i种颜色的染色方案数
ans $=\sum_{i=1}^N \binom{K}{i} s(i)$
枚举s(1..n)的话,用 abc213G的 subset dp,需要$O(n3^n)$
subset dp 可以用 子集卷积 优化
$(f \ast g)(S) = \sum_{T \subseteq S} f(T) g(S \setminus T).$
原始需要$O(3^N)$, 子集dp 需要调用n次
可以优化到 $O(n^2 2^N)$
F(S) = int(bool(S 是一个非空独立集合 non-empty indepenedent set))
$f^K$ 为$F(S)$的K次卷积, $f^n(S)$的意义: 就是 每个独立集(非空)一个颜色,因为是独立集所以里面的点两两不相邻,n次卷积就是n种颜色
$V$是顶点集合
ans $=\left(\sum_{i=1}^{\min(K, N)} \binom{K}{i} f^i \right)(V)$ )(这里官方题解幂次写错了)
注意到(如果 $n = 0$ 或者 $n\ge 0$)时 $f^n(S) = 0$, 所以, 可以修改 求和的上下界
ans $=\left(\sum_{i=0}^K \binom{K}{i} f^i\right)(V).$
如果让$g(S) =$ bool(S是否为独立集合(可为空)), 则表达式$=g^K(V)$ 表示的就是 小于等于k个独立集合的染色方案, 也= ans
如果$m$比较小
容斥原理, 对于边集$E$的子集合$P$, 计算
$\sum_{P \subseteq E} (-1)^{|P|} K^{k(V, P)}.$ 幂次就是上面的 在指定边集$P$以后的连通块数量
复杂度$O(N2^M)$
$F(G) =$, 图$G$颜色$K$的方案数
$F(G) = F(G去掉边e(不去掉点)) - F(G把e两点合并)$ (其实就是是否选e,对应上面把容斥的(-1)展开)
如果$G$有独立点$v$, $F(G)=KF(G去掉v)$, 相当于处理孤立点(这里官方题解又写错了, denotes a removal of a vertex)
如果$G$有度为1的点, $F(G)=(K-1)F(G去掉v)$
对于度为$2$的点$u$,设它相连的边$e_1,e_2$
$F(G)=F(G去掉e_1去掉e_2)-F(G去掉e_1选中e_2)-F(G选中e_1去掉e_2)+F(G选中e_1选中e_2)$
$=KF(G去掉u)-F(G去掉u)-F(G去掉u)+F(G选中e_1选中e_2)$
$=(K-2)F(G去掉u)+F(G选中e_1选中e_2)$
注意到这里 是少两条边,同时状态分叉两个, 所以总状态会分叉到约$2^{M/2}$个
如果所有点度数都大于3, 则 被连的点$\le (2M/3)$, 用点比较少的方法
如果继续考虑 度=3 的情况, 那么 被连的点$\le (2M/4)$,就可以subset dp ($3^{15}=14348907$)
而度=3的情况$-$表示不选,$+$表示选
$F(G) = F(-e_0-e_1-e_2)-F(-e_0-e_1+e_2)-F(-e_0+e_1-e_2)+F(-e_0+e_1+e_2)-F(+e_0-e_1-e_2)+F(+e_0-e_1+e_2)+F(+e_0+e_1-e_2)-F(+e_0+e_1+e_2)$
$= KF(-u)-3F(-u)+F(-e_0+e_1+e_2)+F(+e_0-e_1+e_2)+F(+e_0+e_1-e_2)-F(+e_0+e_1+e_2)$
$= (K-3)F(-u)+F(-e_0+e_1+e_2)+F(+e_0-e_1+e_2)+F(+e_0+e_1-e_2)-F(+e_0+e_1+e_2)$
分叉 $5^{M/3}$, $5^{10}=9765625$
代码
1 |
|
其它
https://www.luogu.com.cn/blog/0x3F/solution-at-abc294-h
有个 利用奇偶性的 暴力dfs+不压缩路径的并查集, 但是7.7s 贴着8s过的
因为 如果dfs中 [1…i-1]i [i+1..n] 选中i时和不选i的并查集关系一样, 那么后续的所有状态对应的 k^{点数}对应相等,而(-1)^{count(属性)} 一正一负正好抵消, 所以这种情况直接返回0剪枝
总结
Ex
有想到容斥,但是没做过子集卷积的
另外这个简化其实还挺自然的,竟然没想到
所以这里可以直接特殊讨论+子集dp就行了, 没有学会子集卷积