普通生成函数学习笔记&做题记录
啥是普通生成函数
已知一个序列 \(a\),可以有限项也可以无限项,定义其生成函数 \(F(x)\) 为。
举个例子。
的生成函数是 \(F(x)=1+2x+3x^2\)。
的生成函数是 \(F(x)=\sum (i+1)x^i\)。
有啥用
生成函数本质是一个多项式,所以可以进行多项式卷积,方便处理序列问题。
假设序列 \(a\) 的生成函数是 \(F(x)\),序列 \(b\) 的生成函数是 \(G(x)\)。
封闭形式
封闭操作可以让生成函数更加易于化简。
简而言之就是把无限项的多项式封闭为有限项。
比如 \(F(x)=\sum x^i\)。
可以列出方程
解出 \(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}\)
本质上是二项式定理的负数形式(也叫牛顿二项式定理)。
考虑证明一下。
用归纳法证明,对 \(n=1\) 时前面已经证明过了,成立。
设生成函数 \(F_n(x)=\sum \binom{n-1+i}{i}x^i\)。
相减这一步可以在杨辉三角上显然得证。
然后可以得到
原定理得证。
这个证明是之前写的,实在是太逊了。
考虑组合意义,\(\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}\)。
- 其他形式
一般来说可以拆成多个生成函数之和或者差,比如
然后就可以直接做了。
展开形式
\([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)=\frac{x}{1-x-x^2}\)。
然后咋展开?
发现这不属于我们之前列到的任何一种情况。
一种展开方式是把分母中 \(x+x^2\) 看做整体展开,不过不是我们想要的结果。
一种简单的方法是把分母是 \(2\) 次的式子换成两个 \(1\) 次的式子相加。
设
解出 \(A=\frac{1}{\sqrt{5}},A=-\frac{1}{\sqrt{5}},a=\frac{1+\sqrt{5}}{2},b=\frac{1-\sqrt{5}}{2}\)
把两个式子分别展开,加起来就是 \(F(x)\) 的展开形式了。
这样就得到了我们熟悉的形式。
更多构造、计算生成函数的技巧还是在习题中吧。
做题记录
思维难度基本递增。
有 \(8\) 种物品,每个物品有自己的限制,现在要拿 \(n\) 个物品,求方案数,限制有点多,建议看原题。
经典板子题,考虑对于每一种食物构造一个生成函数,每一项表示这种食物选多少个。
以 承德汉堡
为例,直接构造 \(F(x)=\sum x^{2i}\)。
求出每一个函数的封闭形式,然后全部卷积起来,再展开就是答案。
函数都比较简单,不细讲。
有两个人抛硬币,分别抛 \(a,b\) 次 \((b\le a\le b+10^4)\),问有多少种方案使得第一个人正面次数大于第二个人。
生成函数简单题。
考虑对于两者之差,第一个人要么加一要么不变,第二个人要么减一,要么不变。
容易构造出
答案就是
化简一下
最后的式子相当于求一个杨辉三角上一行的一个前缀和。
考虑 \(a,b\) 差很小,可以发现前缀和实际上是整行的一半再加上一些或减去一些东西。
众所周知,一整行的和是 \(2^{a+b}\),所以可以直接知道一半的和是多少,然后算一下少的就好了。
出题人很凉心,模数 \(10^k\) 不是质数,需要用 exLucas,不会的可以看 我的博客。
有 \(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\) 的答案,容易得到:
因为下面的状态前面要写 \(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)\) 换掉,得到。
求一下数列通项,令 \(H_n(x)=\frac{F_n(x)(1-x)^n}{x^n}\)。
计算一下 \(F_1(x)\)。
\(F_1(x)=\frac{x(2-x)}{(1-x)^2}\)。
\(H_1(x)=\frac{2-x}{1-x}\)。
然后就可以推出 \(H\) 的通项了。
直接用 Lucas 算就好了。
给定 \(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\) 个球有三种情况,染黑,染白,不染。
枚举染白的,然后就可以转化为:
然后构造一下,加一下项,变成卷积形式.
答案就是
会发现这个东西比较阴间考虑枚举 \(b\),乘上 \((2+x)\) 直接暴力做,除以 \((1+x)\) 就是乘上 \(\sum (-1)^ix^i\) 发现和奇偶性有关,记录一下奇偶性的和做就好了。
时间复杂度 \(O(m^2)\)。
ABC241Ex *2881
已知有 \(n\) 种物品,第 \(i\) 种物品的价值都是 \(a_i\),一共有 \(b_i\) 个,现在拿出 \(m\) 个物品,总价值为选的物品的价值的乘积,问所有选取方案的和,注意同种物品被视作是相同的,答案对 \(998244353\) 取模。
\(n\le 17,m\le 10^{18},b_i\le 10^{17}\)。
发现有和的限制,考虑构造生成函数。
答案就是第 \(m\) 项的系数。
然后考虑化简一下。
上面的部分比较简单,直接 \(2^n\) 枚举选择那些取 \(a_i^{b_i+1}x^{b_i+1}\) 这一项,就可以计算出对应的 \(x\) 的指数与系数,现在考虑下面的怎么算。
构造一下。
考虑如何计算出 \(c_i\)。
然后考虑将 \(x\) 带入为 \(a_i^{-1}\)。
结果发现其他项都变成了零。
然后直接计算,得到
\(c_i\) 现在已知,考虑将前面的式子中的 \(\dfrac{c_i}{1-a_ix}\) 展开。
于是变成
这样的话,前面直接枚举,后面的系数可以直接算就做完了。
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)!}\)。
因此答案就是
那个和等于 \(2n-2\) 比较阴间,因此直接生成函数:
后面的 \(j\) 就是在枚举 \(a_i\)。
直接计算即可。