普通生成函数学习笔记&做题记录

啥是普通生成函数

已知一个序列 \(a\),可以有限项也可以无限项,定义其生成函数 \(F(x)\) 为。

\[F(x)=\sum a_ix^i \]

举个例子。

\[a=\left \langle 1,2,3 \right \rangle \]

的生成函数是 \(F(x)=1+2x+3x^2\)

\[a=\left \langle 1,2,3...\right \rangle \]

的生成函数是 \(F(x)=\sum (i+1)x^i\)

有啥用

生成函数本质是一个多项式,所以可以进行多项式卷积,方便处理序列问题。

假设序列 \(a\) 的生成函数是 \(F(x)\),序列 \(b\) 的生成函数是 \(G(x)\)

\[F(x)G(x)=\sum x^i\sum_{j=0}^i a_jb_{i-j} \]

封闭形式

封闭操作可以让生成函数更加易于化简。

简而言之就是把无限项的多项式封闭为有限项。

比如 \(F(x)=\sum x^i\)

可以列出方程

\[F(x)=xF(x)+1 \]

解出 \(F(x)=\frac{1}{1-x}\),这样就得到了生成函数的封闭形式。

几种比较常见的封闭形式:

  • \(\frac{1}{(1-x)^n}\)

这种函数有下面几种:

\(\left \langle 1,1,1,1...\right \rangle=\frac{1}{1-x}\)

\(\left \langle 1,2,3,4...\right \rangle=\frac{1}{(1-x)^2}\)

\(\left \langle 1,3,6,10...\right \rangle=\frac{1}{(1-x)^3}\)

\(\left \langle \binom{n}{1},\binom{n+1}{2},\binom{n+2}{3},\binom{n+3}{4}...\right \rangle=\frac{1}{(1-x)^n}\)

本质上是二项式定理的负数形式(也叫牛顿二项式定理)。

\[(1-x)^{-n}=\sum \binom{n-1+i}{i}x^i \]

考虑证明一下。

用归纳法证明,对 \(n=1\) 时前面已经证明过了,成立。

设生成函数 \(F_n(x)=\sum \binom{n-1+i}{i}x^i\)

\[F_n(x)-F_{n-1}(x)=\sum (\binom{n-1+i}{i}-\binom{n-2+i}{i})x^i\\ =\sum\binom{n-2+i}{i-1}x^i=xF_n(x) \]

相减这一步可以在杨辉三角上显然得证。

然后可以得到

\[F_n(x)=\frac{F_{n-1}(x)}{1-x}=(1-x)^{-n} \]

原定理得证。

这个证明是之前写的,实在是太逊了。

考虑组合意义,\(\frac{1}{1-x}=\sum x^i\),也就是考虑有 \(n\) 堆石子,每堆有无限个,然后一堆可以选任意多个,求选 \(i\) 个的方案数,这个显然就是插板法了。

  • \(\frac{1}{1-nx}\)

这种就是等比数列求和,对应的序列是

\(\left \langle 1,n,n^2,n^3...\right \rangle\)

  • \(\frac{1}{1-x^n}\)

这种比较简单,比如 \(\sum x^{ni}\),你把它变成 \(\sum (x^n)^i\)\(x^n\) 视作一个整体,用上面的做就好了。

  • \((1+x)^n\)

这也不大难,直接二项式定理,它对应展开形式是 \(\sum \binom{n}{i} x^i\)

  • 有一堆前导零。

比如说 \(a=\left \langle 0,0,...0,0,1,2,3,4\right \rangle\)

前面有 \(n\) 个零,那就先把 \(0\) 后面的结果算出来,再右移,相当于乘上一个 \(x^n\)

上面的答案是 \(\frac{x^n}{(1-x)^2}\)

  • 其他形式

一般来说可以拆成多个生成函数之和或者差,比如

\[\sum ix^i=\sum (i+1)x^i-\sum x^i \]

然后就可以直接做了。

展开形式

\([x^n]F(x)\) 表示 \(x^n\) 的系数。

现在成功求出了 \(F(x)\) 的封闭形式,那么咋求 \([x^n]F(x)\) 呢?此时需要去展开。

实际上就是封闭的逆过程,一般的方法是设关于 \(F(x)\) 的方程然后求解。

来个简单的例子:

\(F(x)=\frac{1}{x^2+1}\) 的展开形式。

这个东西先考虑把 \(x^2\) 换成 \(x\) ,算出结果后只需要所有 \(x\) 项开平方即可。

那么考虑 \(F(x)=\frac{1}{x+1}\),列出 \((x+1)F(x)=1\)

容易得到 \(a_1=1,a_i=-a_{i-1}\),所以可以得到 \(F(x)=\sum (-x)^n\)

换回去,得到 \(F(x)=\sum (-1)^n x^{2n}\)

再来个例子:

求斐波那契数列(\(f_1=f_2=1,f_i=f_{i-1}+f_{i-2}(i\ge 3)\))第 \(n\) 项的值,对 \(10^9+7\) 取模。

\(O(n)\),我会递推!

\(O(\log n)\),我会矩阵快速幂!

\(O(1)\)我会矩阵块速幂,我知道通项公式!

尽管斐波那契数列的通项已经变成地球人都知道了的常识,我们还是尝试用生成函数来推出它。

设生成函数 \(F(x)=\sum f_ix^i\)

列方程。

\[F(x)-xF(x)=x^2F(x)+x \]

得到封闭形式 \(F(x)=\frac{x}{1-x-x^2}\)

然后咋展开?

发现这不属于我们之前列到的任何一种情况。

一种展开方式是把分母中 \(x+x^2\) 看做整体展开,不过不是我们想要的结果。

一种简单的方法是把分母是 \(2\) 次的式子换成两个 \(1\) 次的式子相加。

\[\frac{x}{1-x-x^2}=\frac{A}{1-ax}+\frac{B}{1-bx} \]

解出 \(A=\frac{1}{\sqrt{5}},A=-\frac{1}{\sqrt{5}},a=\frac{1+\sqrt{5}}{2},b=\frac{1-\sqrt{5}}{2}\)

把两个式子分别展开,加起来就是 \(F(x)\) 的展开形式了。

\[F(x)=\sum x^i\frac{1}{\sqrt{5}}((\frac{1+\sqrt{5}}{2})^i-(\frac{1-\sqrt{5}}{2})^i) \]

这样就得到了我们熟悉的形式。

更多构造、计算生成函数的技巧还是在习题中吧。

做题记录

思维难度基本递增。


BZOJ3028

\(8\) 种物品,每个物品有自己的限制,现在要拿 \(n\) 个物品,求方案数,限制有点多,建议看原题。

经典板子题,考虑对于每一种食物构造一个生成函数,每一项表示这种食物选多少个。

承德汉堡 为例,直接构造 \(F(x)=\sum x^{2i}\)

求出每一个函数的封闭形式,然后全部卷积起来,再展开就是答案。

函数都比较简单,不细讲。


P3726

有两个人抛硬币,分别抛 \(a,b\)\((b\le a\le b+10^4)\),问有多少种方案使得第一个人正面次数大于第二个人。

生成函数简单题。

考虑对于两者之差,第一个人要么加一要么不变,第二个人要么减一,要么不变。

容易构造出

\[F(x)=(1+x)^a(1+\frac{1}{x})^b \]

答案就是

\[\sum_{i=1}^{a} [x^i]F(x) \]

化简一下

\[\sum_{i=1}^{a} [x^i](1+x)^a(1+\frac{1}{x})^b=\sum_{i=1}^a [x^i]x^a(1+\frac{1}{x})^{a+b}=\sum_{i=1}^a \binom{a+b}{a-i} \]

最后的式子相当于求一个杨辉三角上一行的一个前缀和。

考虑 \(a,b\) 差很小,可以发现前缀和实际上是整行的一半再加上一些或减去一些东西。

众所周知,一整行的和是 \(2^{a+b}\),所以可以直接知道一半的和是多少,然后算一下少的就好了。

出题人很凉心,模数 \(10^k\) 不是质数,需要用 exLucas,不会的可以看 我的博客


P7386

\(n\)\(1\)\(m\)\(0\),你需要把它们排列,但要保证任意的 \(1\) 互不相邻且第一个位置是 \(0\)、最后一个位置是 \(1\),现在把所有可以构造出的串放到一棵 0-1 Trie 上,需要多少个节点,此处 0-1 Trie 的节点存字符而非边。
答案对 \(18888913\)(一个质数),取模。
\(n,m\le 5\times 10^{18}\)

由于最前面是 \(0\),最后是 \(1\),所以字符串可以看做是一大堆 \(0\) 后面跟个 \(1\) 拼起来。

考虑 dp,设 \(f_{n,m}\) 表示 \(n\)\(1\)\(m\)\(0\) 的答案,容易得到:

\[f_{n,m}=\sum_{i=1}^m (f_{n-1,m-j}+2) \]

因为下面的状态前面要写 \(01\),所以要加二。

并且显然如果 \(n>m\),无解。

考虑这东西用生成函数做,设 \(F_n(x)=\sum f_{n,i}x^i\)

考虑咋推到下一个,设 \(G(x)=\sum x^i=\frac{1}{1-x}\)

相当于 \(i\ge n\) 的每项加 \(2\),然后前缀和后后移一位。

容易发现 \(F_{n+1}(x)=(F_n(x)+2G(x)x^n)G(x)x\)

\(G(x)\) 换掉,得到。

\[F_{n+1}(x)=(F_n(x)+\frac{2x^n}{1-x})\frac{x}{1-x} \]

求一下数列通项,令 \(H_n(x)=\frac{F_n(x)(1-x)^n}{x^n}\)

\[H_{n+1}(x)=H_n(x)+2(1-x)^{n-1} \]

计算一下 \(F_1(x)\)

\[1+F_1(x)=\sum (i+1)x^i=\frac{1}{(1-x)^2} \]

\(F_1(x)=\frac{x(2-x)}{(1-x)^2}\)

\(H_1(x)=\frac{2-x}{1-x}\)

然后就可以推出 \(H\) 的通项了。

\[H_n(x)=\frac{2-x}{1-x}+\sum_{i=0}^{n-2} 2(1-x)^i=\frac{2-x}{1-x}+\frac{2-2(1-x)^{n-1}}{x}\\ F_n(x)=\frac{x^n(2-x)}{(1-x)^{n+1}}+\frac{x^{n-1}(2-2(1-x)^{n-1})}{(1-x)^n}=\\ \frac{x^{n-1}(2-x^2)}{(1-x)^{n+1}}-\frac{2x^{n-1}}{1-x}\\ ans=[x^m]F_n(x)=[x^{m-(n-1)}]\frac{F_n(x)}{x^{n-1}}\\ =[x^{m-(n-1)}](\frac{2-x^2}{(1-x)^{n+1}}-\frac{2}{1-x}) \]

\[=[x^{m-(n-1)}]((2-x^2)\sum \binom{n+i}{n} x^i)-2 \\ =2\binom{m+1}{n}-\binom{m-1}{n}-2 \]

直接用 Lucas 算就好了。

code


P7481

给定 \(n,m\) ,保证 \(m\le n\),令 \(F(a,b)=\sum_{i=0}^{b}\binom{b}{i}\binom{n-i}{a}\)
\(\bigoplus_{a=1}^{m}\bigoplus_{b=1}^{m}(F(a,b) \bmod 998244353)\)
其中 \(\oplus\) 表示异或运算。

考虑组合意义,相当于 \(n\) 个球,在前 \(b\) 中选择 \(i\) 个染黑,然后把剩下的选 \(a\) 个染白。

发现前 \(b\) 个球有三种情况,染黑,染白,不染。

枚举染白的,然后就可以转化为:

\[\sum_{i=0}^b 2^{b-i}\binom{b}{i}\binom{n-b}{a-i} \]

然后构造一下,加一下项,变成卷积形式.

\[\sum_{i=0}^b 2^{b-i}\binom{b}{i}x^i\binom{n-b}{a-i}x^{a-i}=(2+x)^b(1+x)^{n-b} \]

答案就是

\[[x^a](2+x)^b(1+x)^{n-b} \]

会发现这个东西比较阴间考虑枚举 \(b\),乘上 \((2+x)\) 直接暴力做,除以 \((1+x)\) 就是乘上 \(\sum (-1)^ix^i\) 发现和奇偶性有关,记录一下奇偶性的和做就好了。

时间复杂度 \(O(m^2)\)

code


ABC241Ex *2881

已知有 \(n\) 种物品,第 \(i\) 种物品的价值都是 \(a_i\),一共有 \(b_i\) 个,现在拿出 \(m\) 个物品,总价值为选的物品的价值的乘积,问所有选取方案的和,注意同种物品被视作是相同的,答案对 \(998244353\) 取模。
\(n\le 17,m\le 10^{18},b_i\le 10^{17}\)

发现有和的限制,考虑构造生成函数。

\[F(x)=\prod (1+a_ix+a_i^2x^2...a_i^{b_i}x^{b_i}) \]

答案就是第 \(m\) 项的系数。

然后考虑化简一下。

\[F(x)=\prod \frac{1-a_i^{b_i+1}x^{b_i+1}}{1-a_ix} \]

上面的部分比较简单,直接 \(2^n\) 枚举选择那些取 \(a_i^{b_i+1}x^{b_i+1}\) 这一项,就可以计算出对应的 \(x\) 的指数与系数,现在考虑下面的怎么算。

构造一下。

\[\prod \frac{1}{1-a_ix}=\sum \frac{c_i}{1-a_ix} \]

考虑如何计算出 \(c_i\)

\[\sum (c_i\prod_{i\ne j} (1-a_jx))=1 \]

然后考虑将 \(x\) 带入为 \(a_i^{-1}\)

结果发现其他项都变成了零。

\[\sum (c_i\prod_{i\ne j} (1-a_ja_i^{-1}))=(c_i\prod_{i\ne j} (1-a_ja_i^{-1}))=1 \]

然后直接计算,得到

\[c_i=(\prod_{i\ne j} (1-a_ja_i^{-1}))^{-1} \]

\(c_i\) 现在已知,考虑将前面的式子中的 \(\dfrac{c_i}{1-a_ix}\) 展开。

于是变成

\[F(x)=(\prod (1-a_i^{b_i+1}x^{b_i+1}))(\sum c_i(1+a_ix+a_i^2x^2...)) \]

这样的话,前面直接枚举,后面的系数可以直接算就做完了。

code


ARC106F *2755 \(\color{blue}\bigstar\)

\(n\) 个点,第 \(i\) 个点上有 \(d_i\) 个孔,孔之间互不相同,点有标号,一个孔最多连一条边,求生成树个数。

\(n\le 2\times 10^5,d_i< 998244353\)

不错的数学推导题。

考虑 prufer 的经典结论,假如钦定 \(i\) 的度数为 \(a_i\),那么生成树个数就是 \(\frac{(n-2)!}{\prod (a_i-1)!}\)

因此答案就是

\[\sum_{\sum a_i=2n-2} \frac{(n-2)!}{\prod (a_i-1)!}\prod \binom{d_i}{a_i}a_i!\\ = (n-2)!\sum_{\sum a_i=2n-2} \prod \binom{d_i}{a_i}a_i\\ = (\prod d_i)(n-2)!\sum_{\sum a_i=2n-2} \prod \binom{d_i-1}{a_i-1} \]

那个和等于 \(2n-2\) 比较阴间,因此直接生成函数:

\[=(\prod d_i)(n-2)![x^{2n-2}]\prod_{i=1}^n \sum_{j=1}^{d_i} \binom{d_i-1}{j-1}x^j \]

后面的 \(j\) 就是在枚举 \(a_i\)

\[=(\prod d_i)(n-2)![x^{2n-2}]\prod_{i=1}^n \sum_{j=0}^{d_i-1} \binom{d_i-1}{j}x^{j+1}\\ =(\prod d_i)(n-2)![x^{2n-2}]x^n\prod_{i=1}^n \sum_{j=0}^{d_i-1} \binom{d_i-1}{j}x^{j}\\ =(\prod d_i)(n-2)![x^{n-2}]\prod_{i=1}^n (1+x)^{d_i-1}\\ =(\prod d_i)(n-2)![x^{n-2}] (1+x)^{(\sum d_i)-n}\\ =(\prod d_i)(n-2)!\binom{(\sum d_i)-n}{n-2}\\ =(\prod d_i)((\sum d_i)-n)^{\underline {n-2}} \]

直接计算即可。

code

posted @ 2022-03-23 11:05  houzhiyuan  阅读(278)  评论(1编辑  收藏  举报