集合幂计数
以下均为无向图,对不同形态的边子图计数。带大家从头到尾玩一遍。
你问我逐点迭代是什么?把集合幂级数看成
0. 数子图
热身题。答案显然是
1. 数连通子图
注意到连通的 exp 是任意,因此把问题 1 得到的集合幂级数求个 ln 即可。复杂度
2. 数(无根)生成树
逐点迭代法。每次加一个最大点,对不超过它的那些部分做次 exp。复杂度是
3. 数森林
对问题 3 做一次 exp,复杂度
4. 数链
随便找一个点作为开头然后 dp,别忘了长度
5. 数环
要固定一个环上最大的点开始 dp,和链几乎相同,最后也别忘了
练习 1:数固定起终点的杏仁
先用问题 4 得到杏仁的一条路的方案数,再 exp 一下即可。
6. 数连通欧拉图
大致等价于每个点度数都是偶数。但是会有问题就是不连通,如果不限制连通性能做的话,把其求个 ln 就好了。接下来考虑如何计数每个点度数都是偶数的边子图数量。
对每条边选/不选设置一个权值
7. 数边仙人掌/沙漠
要开始在刻画上面上难度了。注意到边仙人掌等价于每个点双是单点,一条边,或者是一个环。可以先用问题 5 得到一个集合
问题变成:对所有边子图,对其所有点双的方案数的乘积求和。这就是一个标准的点双连通-连通变换。
做法是设一个集合幂级数列
时间复杂度
8. 数点仙人掌
和问题 7 比较类似,不过刻画方法是每个 边双 都是单点或环,用问题 5 得到每个集合
接下来考虑对其做边双连通-连通变换:
设集合幂级数列
时间复杂度
9. 数点双/边双连通子图
刚才已经介绍了点/边双连通-连通变换,接下来讲下它的逆变换,也就是连通-点/边双连通变换。
点双逆回来时很容易的。因为只有一次 exp,自然 ln 回来即可。
边双乍一看没法做(如果你不和我一样唐就当我没说这句话),但你仔细想下,exp 的部分并没改变过,所以可以直接 exp 倒数算出来,乘回去就好了。
回到原题,如果分别把点/边双的贡献设为
时间复杂度
10. 数匹配
原题数据范围很奇怪,
考虑如何刻画匹配。一个有点困难,自由度有点高,不如先固定另一个匹配,把这两个匹配叠起来。一个边子图是匹配当且仅当每个点度数
那怎么找固定匹配呢?其实最好要求每个点都要出现在匹配中,这样很多对点就被“捆绑”起来了!因此,先不妨设
这时,你再关注每个连通块。不难发现,大小一定是偶数,因为固定匹配的匹配点一定成对出现。于是集合只有
那这里链和环的方案数其实是分别和问题 4,5 是类似的,也可以
分别设链和环对应的集合幂级数为
总复杂度
11. 数固定大小匹配
按刚才那个做法直接做是
首先有个弱化版 Fast as Ryser,给了个常数
如果不固定大小