生成函数小记
生成函数 趣味知识
分拆数与欧拉五边形数定理
Cayley 公式
\(n\) 个点的有标号有根树个数为 \(n^{n-1}\),\(n\) 个点的有标号无根树个数为 \(n^{n-2}\)。
这两点可以用 Prufer 序列极为简单地证明出来,也可以用 matrix-tree 定理较为简单地证明。
当然也可以使用生成函数证明。
记 \(\hat G(x)\) 表示 \(n\) 个点有标号的有根树的个数的 EGF。
那么考虑他的儿子,容易列出等式:
然后构造一个 EGF \(\hat F(x)=x\exp (-x)\)。
会发现 \(\hat F(x),\hat G(x)\) 互为复合逆。
然后有拉格朗日反演:
我们就得到了 \(n![x^n]\hat F(x)=n^{n-1}\)。
ex - 有根森林与固定根树的计数
对于 \(n\) 个点的有根森林,显然可以与 \(n+1\) 个点的无根树构成双射,理由是存在可逆构造方法:将后者中的编号为 \(n+1\) 的点删去,一定得到不同的无根树,否则存在某两棵树相同;反之亦然。
因此 \(n\) 个点的有根森林的个数为 \((n+1)^{n-1}\)。
同时假定要求 \(1,\cdots,k\) 分别为 \(k\) 个连通部分的有根森林的根,记它的个数为 \(T_{n,k}\),则有 \(T_{n,k}=kn^{n-k-1}\)。
考虑归纳法证明,假设对于 \(n'<n\) 的 \(\forall T_{n',k}\)满足上述命题。
考虑:
上式的组合意义是在 \(n\) 个点中选择编号最小的根去掉,枚举 \(j\) 为这个根的儿子数量,同时组合数是在考虑标号。
exp 和 ln 的组合意义
对于 \(x\) 而言,我们知道有泰勒展开式:
因此在我们要计算多重集问题但是同时不考虑顺序时可以使用上述的技巧去掉一些不易去除的系数。
考虑对于集合划分问题:
一个集的贡献的生成函数应该为:
现在考虑两个集的情况,实际上它的生成函数应该是:
因为会发现卷积的组合意义对于 \(x^{a+b}\) 来说是有先后顺序的,\(a=b\) 时也是如此,比如 \([1,2,3,4]\) 中第一次选择了 \([1,2]\) 而第二次选择 \([3,4]\),实际上和第一次选择 \([3,4]\) 而第二次选择 \([1,2]\) 的意义是一样的,但是在 EGF 中会算两次,因此我们需要除掉这个系数。
而更高次项也是如此,因此,最后由任意多个环构成的图的生成函数应该如下:
实际上在考虑圆排列时 \(\ln\) 的应用也存在,这里就不展开了。
生成函数 练习题
HDU-2065
statement
给出 \(n\) ,要求以四种字符组成长度为 \(n\) 的序列,并且要求给定的两种字符恰好出现偶数次。
solution
HDU-2152
statement
\(n\) 种水果,每种水果最多买 \(b_i\) 个,最少买 \(a_i\) 个,问有多少种购买方案。
solution
其实可以背包,但是应该练习 GF。
HDU-1709
statement
给出 \(n\) 个砝码,问有哪些比砝码总重量小的重量无法称出。
solution
背包或者 GF。GF 可以用分治 FFT。
Codeforces-891E
statement
给出 \(n\) 个数 \(a_1,a_2,\dots,a_n\) 。
接下来要进行 \(k\) 次操作,每次随机选择一个数 \(x \in [1,n]\),把 \(a_x\) 减一,并将答案增加除 \(a_x\) 外所有数的乘积。
求最终答案的期望,答案对 \(10^9 + 7\) 取模。
\(n\le 5000;a_i,k\le10^{9}\)。
solution
容易发现每次的变化量实际上是 \(-\prod a_i\) 的变化量,因此答案应该等于 \(\prod a_i-\prod (a_i-b_i)\)。
因此求后面的期望:
令:
因此有:
时间复杂度 \(O(n^2)\) 或 \(O(n\log_2n)\) (分治求卷积),瓶颈在于求 \(\prod (a_i+x)\) 的各项系数。
Atcoder-abc241h
statement
有一些卡牌,每张卡牌上有一个数字,具体的,有 \(b_i\) 张卡牌上的数字为 \(a_i\)。
求出拿走其中 \(m\) 张卡牌的贡献之和。贡献为这些卡牌的乘积。对于本质相同的卡牌组合,只算一次。
答案对 \(998244353\) 取模。
\(n\le 16;m\le 10^{18};b_i\le 10^{17};a_i<\mathrm{mod}\)。
solution
考虑:
问题在于如何求出 \(\lambda_i\)。
发现 \(\sum \lambda_i \prod_{i\ne j}(1-a_jx)=1\),因此对于 \(\lambda_k\) 我们令 \(x=\frac{1}{a_k}\),这样和式中只有 \(i=k\) 位置上的值不为 \(0\)。因此:
至于为什么一定存在这样的 \(\lambda\),带进去化简就可以得到了。
LibreOJ-#6570
statement
定义毛毛虫树为一棵树,满足存在一个链,所有点到链的距离小于等于 \(1\)。
计数 \(n\) 个点的有标号毛毛虫树的个数,答案对 \(998244353\) 取模。
\(n\le 10^5\)。
solution
容易想到一种简单的思路,即根据链把点进行划分,然后指数生成函数计数,但是问题是两边的端点会寄掉。
因此强制令两边的端点必须接上其他点。
把中间的生成函数记为 \(\hat F(x)\),两端的记为 \(\hat G (x)\)。则有:
而答案就是:
但是这个值有两点问题,一是没有考虑菊花的情况,二是首尾颠倒算一种。因此:
Luogu-P6049
statement
求 \(n\) 个点的带权带标号有根树的个数,其中权值满足父亲的权值大于等于儿子的,且权值范围为 \([1,m]\)。
答案对 \(998244353\) 取模。
\(n\le 400,m< 998244353\)
solution
首先有一个性质就是答案是一个关于 \(m\) 的 \(n\) 次多项式。
证明:会发现只需要考虑相对的权值大小,乘上组合数即可。而出现的不同权值个数最多只有 \(n\) 个。
于是令 \([x^n]\hat F_k(x)\) 表示考虑根的权值为 \(k\) 时大小为 \(n\) 的树(满足题目要求)的个数,然后记 \(\hat G_k(x)\) 表示其前缀和。
因此考虑求出 \(\forall k\in[1,n+1],[x^n]\hat G_k(x)\)。
而后很容易通过组合意义列出式子:
然后因为存在一种 \(O(n^2)\) 递推 \(A(x)[1,\cdots,n]\to \exp(A(x))[1,\cdots,n]\) 的方法:
我们将 \(\exp(A(x))[1,\cdots,n]\) 记为 \(\exp_n(A(x))\)
因此我们可以在 \(O(n^3)\) 的时间复杂度内求出 \(\forall k\in[1,n+1],[x^n]\hat G_k(x)\)。
然后拉格朗日插值公式求出这个多项式在 \(m\) 处的取值。
本文作者:saubguiu
本文链接:https://www.cnblogs.com/imcaigou/p/18127934
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步