OI-WIKI。
普通生成函数
F(x)=n∑anxn
a 可以是有穷序列,也可以是无穷的。
基本运算
加法运算:
F(x)±G(x)=n∑(an±bn)xn
乘法运算(卷积):
F(x)G(x)=n∑xni=0∑naibn−i
封闭形式
例如 ⟨1,1,1,⋯⟩ 的普通生成函数 F(x)=∑n≥0xn:
F(x)x+1=F(x)F(x)=1−x1
HDU - 2152 Fruit
HDU - 2152 Fruit。
每个水果选 ai 到 bi 个之间,一共选 m 个,问方案数。
直接生成函数就做完了:
(xa1+xa1+1+⋯+xb1)(xa2+xa2+1+⋯+xb2)⋯(xan+xan+1+⋯+xbn)
P6300 悔改
P6300 悔改。
这道题标签没有生成函数,但是这个就是生成函数的题,算模板吧。
这种题先设 ci 表示 i 的出现次数。
ansk=21i+j=k∑min(ci,cj)=21d=1∑ni+j=k∑[ci≥d][cj≥d]
我们发现这个很像生成函数的卷积形式,于是我们设生成函数 fd(x):
fd(x)=i∑[ci≥d]xi
然后将 fd(x) 代入:
ansk=21d=1∑nfd(x)2(k)
到现在我们已经推完了生成函数,但是这个还是会 TLE。我们还需要一点注意力,可以发现,d 离散化之后就是 O(n) 级别的了。
然后上面的卷积就用 FFT/NTT 求出来即可,时间复杂度 O(mnlogm)。
指数生成函数
F^(x)=n∑ann!xn
但 F^(x) 实际上也是序列 ⟨n!an⟩ 的普通生成函数。
基本运算
加减法和普通生成函数相同:
F(x)±G(x)=n∑(an±bn)n!xn
乘法运算:
F^(x)G^(x)=i≥0∑aii!xij≥0∑bjj!xj=n≥0∑xni=0∑naibn−ii!(n−i)!1=n≥0∑n!xni=0∑n(in)aibn−i
上面的过程是因为组合数 (in)=i!(n−i)!n!,因此
i!(n−i)!1=n!1(in)
所以:F^(x)G^(x) 是序列
⟨∑i=0n(in)aibn−i⟩
的指数生成函数。
封闭形式
序列 ⟨1,1,1,⋯⟩ 的指数生成函数是:
F^(x)=∑n≥0n!xn=ex
泰勒展开就行了。
exp 函数
很多时候,指数生成函数会和 exp 函数结合:
exp(x)=ex=n=0∑∞n!xn,x∈C
eA(x)=k=0∑∞k!A(x)k
P4726 【模板】多项式指数函数(多项式 exp)。
组合意义
⟨∑i=0n(in)aibn−i⟩
我们发现这个正是把 n 个元素划分成 i 个集合。
广义二项式定理
(a+b)α=k=0∑∞(kα)aα−kbk,
(kα)=k!α(α−1)(α−2)⋯(α−k+1)
广义组合数
经典组合数:
(kn)=k!(n−k)!n!广义组合数:
(kα)=k!α(α−1)(α−2)⋯(α−k+1)当 α 是负整数时,可化为带符号的经典组合数:
(k−n)=(−1)k(kn+k−1),n∈N+
HDU - 1521 排列组合
HDU - 1521 排列组合。
第 i 种物品的生成函数是 1+1!x1+2!x2⋯+ai!xai。
(1+1!x1+2!x2⋯+a1!xa1)(1+1!x1+2!x2⋯+a2!xa2)⋯(1+1!x1+2!x2⋯+an!xan)
最后我们要求 m!xm 的系数。
生成函数的封闭形式
ex=n=0∑∞n!xn=1+x+2!x2+3!x3+4!x4+⋯
e−x=n=0∑∞n!(−x)n=1−x+2!x2−3!x3+4!x4−⋯
POJ - 3734 Blocks
POJ - 3734 Blocks。
红色和绿色的生成函数:
1+2!x2+4!x4+⋯=2ex+e−x
蓝色和黄色的生成函数:
1+1!x1+2!x2+⋯=ex
F(x)=(2ex+e−x)2⋅(ex)2=4e4x+2e2x+1=41+n=0∑∞44n⋅n!xn+n=0∑∞42n+1⋅n!xn=41+n=0∑∞44n+2n+1⋅n!xn
所以最后的答案就是:
4n−1+2n−1(mod10007)
卡特兰数
有一些生成函数的题目需要卡特兰数。而且卡特兰数的递推公式可以用生成函数求。
Cn={1,∑i=0n−1CiCn−1−i,n=0,n>0
数列前几项(可以背一下吧,做题可以瞪):
1,1,2,5,14,42,132,429,1430⋯
卡特兰数还有别的形式:
Cn=n+11(n2n)=n!(n+1)!(2n)!
P3978 [TJOI2015] 概率论
P3978 [TJOI2015] 概率论。
首先,先定义 g 表示二叉树的形态有多少种:
cn=i=0∑n−1gign−1−i
我们发现这正是卡特兰数的形式,通项公式就是用生成函数推的。
然后考虑函数 f 表示 n 个节点的二叉树的节点个数和。
我们考虑从 n−1 转移。可以发现一个有 n−1 个点的二叉树一共有 (n−1)∗2−(n−2)=n 个空余的节点。我们考虑转移后的组合 (T,d) 表示一个树的每一个叶子节点,然后我们可以发现,每一个目标树上的节点都可以从对应的 n−1 的树上转移来,所以:
fi=n∗gi
所以 n 个点二叉树叶子个数等于 n−1 个点的个数 ×n。
例题
CF993E Nikita and Order Statistics
CF993E Nikita and Order Statistics。
反转序列构造卷积形式。
思路
首先这道题很容易想到前缀和。
ansk=l=1∑nr=1∑n[sr−sl−1=k]移项,然后还是用出现次数 c 来表示。
ansk=l=1∑ncsl−1+k然后我们需要消去 s:
ansk=l=1∑n−kci∗ci+k然后这一点也不像卷积的形式,于是...我们设 d 为把 c 反过来的数组,ci=dn−i+1。
ansk=l=1∑n−kci×dn−i−k于是我们用卷积来表示答案:
ansk=c∗d(n−k)
写完代码发现 ans0 一直是错的,然后需要特判。原因:可能会计算 l>r 的情况。
P4451 [国家集训队] 整数的lqp拆分
P4451 [国家集训队] 整数的lqp拆分。
融合生成函数和数论各种知识的好题。
思路
我们可以用 F 表示出选 k 个数的生成函数:
i=0∑+∞f(x)i然后我们考虑写成封闭形式,我们先推导 F 的封闭形式:
f(x)f(x)f(x)=xf(x)+x2f(x)+a0+a1x−a0x=xf(x)+x2f(x)+x=1−x−x2x然后我们再推原来的式子(代入无穷级数公式):
i=0∑+∞f(x)i=i=0∑+∞1−f(x)1=1−2x−x21−x−x2=1+1−x−x2x现在我们需要求这个生成函数的点值:
1−x−x2x设这个为 A:
(1−2x−x2)A(x)=x∑anxn−2∑anxn+1−∑anxn+2=xan=2an−1+an−2然后我们需要求通项公式,需要一个叫特征方程的东西:
rn=2rn−1−rn−2r2−2r−1=0r=1±2上面的方程是能表示出递推关系的,我们只需要解出可以满足 a0 和 a1 的解就行了。
然后通项公式一定是这个形式的(这个是二阶的函数):
an=A(1+2)n+B(1−2)n代入 0 和 1,A=−B,然后解得:
A=221,B=−221通项公式:
an=221(−2+1)n−221(2+1)n然后注意到 2 在 109 下存在。