多项式计数相关

放假太闲了,也没啥游戏可玩,于是学学科技

来自hosen学长的亲切关怀

前言

本博客直接嗯看的话一开始跨度会比较大,因此不建议没有了解过以下内容的人观看。

  • 多项式以及多项式的一些初等函数
  • 生成函数的简单了解,包括 OGF 和 EGF(仅限了解即可)
  • 组合数学

指数生成函数 exp 的组合意义

我们考虑下面这个问题:

n 个不同的小球,我们设 k 个小球放入一个盒子中的方案数为 fk(显然在球和盒子的问题中 fi=1,但是有时我们需要研究 fi 不等于 1 的情况)。求下面两个问题的答案:

  • n 个不同的小球放入 k 个互不区分的盒子中的方案数
  • n 个不同的小球放入任意个互不区分的盒子中的方案数

我们设第一个问题的答案为 Gk[n],枚举 k 个盒子中都放多少个小球,我们有下面的式子:

Gk[n]=n!k!a1+a2+ak=nfa1fa2faka1!a2!ak!

我们设 fi 的 EGF 为 F(x)Gk[i] 的 EGF 为 Gk(x),上面的式子就可以写成:

Gk(x)=1k!Fk(x)

多项式快速幂即可解决。

而对于第二个问题,我们只需要枚举有多少个盒子即可。我们就可以写出下面的式子:

G(x)=i=0+Gi(x)=i=0+Fi(x)i!

根据 ex=i=0+xii!(麦克劳林展开),我们可以得到下面的式子:

G(x)=exp(F(x))

出奇的简洁,对吧。这也就是指数生成函数 exp 的组合意义,既 n 个互异元素划分为任意非空的无序集合中,其中大小为 i 的集合方案数为 fi,最后总方案数为 gn,则两者 EGF 满足 G(x)=exp(F(x))。或者说指示了用有标号的元素构成的集合来生成集族有多少情况

如果上面这些话比较抽象,可以参照下面的两个个例子来理解:

  1. 有标号的小球放到一个盒子是集合,它能够通过 exp 来转化为放到一堆盒子中的情况。
  2. 有标号的点形成连通块是集合,它能够转化为一堆连通块,也就是普通图。

欧拉变换

再回到小球和盒子上来,我们还可以解决下面这几个问题:

  1. 我们认为盒子有序,那么我们前面就不用除去 k!,那么 G(x)=i=0Fi(x)=11F(x)
  2. 无标号小球放入有标号盒子,那么只需要把前面的 EGF 换为 OGF 即可。

我们需要解决的问题主要在下一种:无标号小球放入无标号盒子。我们设生成函数 F(x)=i=0fixi。那么我们对大小为 i 的盒子构造完全背包的生成函数,既 11xi,那么这些盒子的方案数即为 1(1xi)fi,我们就可以得到欧拉变换的定义式:

E(F(x))=i=1+1(1xi)fi

我们考虑把它化简一下,化简的具体过程可以参考我的十二重计数法博客,下面过程可能会略微省略。

E(F(x))=i=1+1(1xi)fi=exp(i=1filn11xi)=exp(i=1fij=1xijj)=exp(j=11ji=1fixij)=exp(i=1F(xi)i)

这样就得到了欧拉变换的最终式子,欧拉变换的组合意义和 exp 类似,但是它主要是用来解决无标号问题的,我们在下面的习题中会看到类似的题目。

一些题目

限于作者能力和精力有限,只能找一些板题来当例题了。

集合划分计数

一个有 n 个元素的集合,将其分为任意个非空无序子集,求方案数。

数据范围:T=10001n105


和上面第一个提到的例子相同,只不过为 fi=[i>0] 的特殊情况。按照上面的式子写即可。

城市规划

n 个点有标号无向连通图的数量。

数据范围:n105


计数杂题中,我们已经介绍了基于 DP 的分治 FFT 做法,这里我们再介绍基于 exp 的组合意义的做法。

我们考虑一张简单无向图是如何组成的:是由一堆有标号点构成的连通块组成的。我们把上面的例子套到这里:小球即为有标号点,盒子即为连通块。只不过这里小球放入一个盒子中的方案数不为 1 了,我们设方案数为 fi。而放到任意多个盒子中的方案数我们设为 gi,易得 gn=2(n2)。根据 exp 的组合意义,很容易得到下面的式子:

G(x)=exp(F(x))F(x)=ln(G(x))

多项式 ln 即可。

有标号 DAG 计数

n 个点有标号的有向无环图进行计数,要求:弱连通图(所有的有向边替换为无向边后的图为连通图)。

数据范围:n105


fi 为大小为 i 的普通 DAG(可能不连通)的数量。

我们考虑模拟拓扑排序的过程,我们删去图中的 j 个零入度点,剩下的图仍然是一张 DAG。我们就能得到下面的式子:

fi=j=1i1(ij)(1)j+1fij2j(ij)

注意这里我们乘了一个 (1)j+1,因为我们注意到我们没有保证恰好 j 个零入度点,所以要容斥一下。而 2j(ij) 是因为这 j 个点可以对剩下的 (ij) 个点选择连或不连边。因此公式为这个。我们考虑化简这个式子:

首先这个 (ij) 很好处理,取两边的 EGF 即可,而对于 2j(ij),我们可以把它用下面这个式子化简:j(ij)=(i2)(j2)(ij2)。这个式子易证,我们就可以把 2j(ij) 化为 2(i2)2(j2)×2(ij2)。这样我们构造下面这两个生成函数:

F(x)=i=0fi2(i2)×i!xi

G(x)=i=0(1)i+12(i2)×i!xi

我们就能得到这个式子:F(x)=F(x)G(x)+1,这里加一是因为有 F[0]=1。解方程即可得到 F(x)=11G(x)

我们得到了普通 DAG 的答案,我们考虑弱连通 DAG。一个普通 DAG 一定是由一堆弱连通的 DAG 构成,因此它也符合我们 exp 的组合意义。因此我们只需要取一下 ln 即可。

无标号无根树计数

n 个点的无标号无根树数量。

数据范围:1n2×105


本题是无标号问题,因此我们需要用上面提到的欧拉变换来解决。

我们先考虑有根树。我们把根去掉后,会形成一堆小的无标号有根树。如果我们把一棵树看作一个集合,那么这一堆树就是生成集族。通过比较系数我们就可以用欧拉变换列出下面的式子:

F(x)=xE(F(x))

这么简洁的式子不出意料的难解决。我们考虑对两边求导。

F(x)=xE(F(x))F(x)=x×exp(i=1F(xi)i)F(x)=x×exp(i=1F(xi)i)+x×(exp(i=1F(xi)i))=F(x)x+x×exp(i=1F(xi)i)×(i=1F(xi)i)=F(x)x+F(x)×(i=1F(xi)×i×xi1i)=F(x)x+F(x)×(i=1F(xi)×i×xi1i)=F(x)x+F(x)(i=1F(xi)×xi1)xF(x)=F(x)+F(x)i=1F(xi)×xi

我们发现右边这个 i=1F(xi)×xi 及其恶心,我们设 G(x)=i=1F(xi)×xi,则

G(x)=i=1F(xi)×xi=i=1xij=1jfjxi(j1)=i=1j=1jfjxij

因此所有对 G(x)n 项系数有 j×fj 的贡献的 j 必须满足 j|n。因此 [xn]G(x)=i|ni×fi

我们再把 G(x) 带回去,能够得到 xF(x)F(x)=F(x)G(x)。而我们发现 xF(x)=i=1i×fi×xi,因此我们能得到下面的式子:

[xn]F(x)=[xn]F(x)G(x)n1fn=i=0n1fignin1

分治 FFT 即可。注意这里的分治 FFT 和 luogu 上的板子题不太一样,gi 是依赖于已经计算过的 fi 的,因此我们需要采取下面的方式转移:

l=0 时,flmid×g0rlfmidr

l0 时,转移为:

flmid×g0rlglmid×f0rl}fmidr

这样我们就求出了有根树的数量,我们再考虑无根树的数量,我们只需要给它定个根:重心。减去不合法的(子树大小大于 n2 的),这样答案即为:

fni=n2+1n1fifni

但是我们考虑偶数个点可能会有两个重心,因此我们需要再减去当这两颗大小相同的树同构的情况,也就是 (fn22),这样就做完了。

未完待续

posted @   crimson000  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示