生成函数

21 篇文章 1 订阅
20 篇文章 0 订阅

也许更好的阅读体验

一般生成函数(OGF)

引入

考虑一类组合对象组成的集合 A A A,其中:

  • 每个元素 a ∈ A a\in A aA都被定义了“大小” ∣ a ∣ |a| a,它是一个非负整数。
  • 对于给定的 n n n,大小为 n n n的元素的数量是有限的,记作 A n A_n An

eg. A A A是全体 01 01 01串组成的集合,一个 01 01 01串的大小被定义为它的长度则 A n = 2 n A_n=2^n An=2n

定义

A ( x ) = ∑ i = 0 ∞ A i x i A\left( x\right) =\sum ^{\infty }_{i=0}A_ix^{i} A(x)=i=0Aixi
A A A的一般生成函数
注意

  • A ( x ) A(x) A(x)为一个多项式
  • 这里的 A i A_i Ai为第 i i i项的 系数

这是一个形式幂级数,不用考虑何时收敛
这里的 x i x^i xi为形式幂,无实义,一般也不会去求
但是 x i x^i xi有区分实际意义的作用,即 x i → x^i\rightarrow xi i i i
x i x^i xi的系数为第 i i i种状态的答案
这个不好说,举个例子
eg.
A A A是全体 01 01 01串组成的集合,则
A ( x ) = ∑ i = 0 ∞ 2 i x i = 1 1 − 2 x \begin{aligned}A\left( x\right) =\sum ^{\infty }_{i=0}2^{i}x^{i}\end{aligned}=\dfrac{1}{1-2x} A(x)=i=02ixi=12x1
最后一步是用的等比数列求和公式,不用考虑何时收敛,所以认为其很大是趋近于0
其中 A i = 2 i A_i=2^i Ai=2i,表示长度为 i i i的答案为 2 i 2^i 2i
x i x^i xi的系数就是长度为 i i i的答案,它是用于区分这个的

运算

有两类组合对象 A A A B B B

  • 定义 C C C A A A B B B的并集
    C ( x ) = A ( x ) + B ( x ) , O ( n ) C(x) =A(x) +B(x),O(n) C(x)=A(x)+B(x)O(n)计算
  • 定义 D D D A A A B B B的笛卡尔积,也即 D D D中每个元素 d d d都是 A A A中某元素 a a a B B B中某元素 b b b拼成的二元组 ( a , b ) (a,b) (a,b),其大小 ∣ d ∣ |d| d 定义为 ∣ a ∣ + ∣ b ∣ |a|+|b| a+b
    D ( x ) = A ( x ) B ( x ) D(x) =A(x)B(x) D(x)=A(x)B(x) F F T FFT FFT乘法 O ( n l o g n ) O(nlogn) O(nlogn)计算

eg:
A A A是全体 01 01 01串组成的集合, B B B是全体字母组成的集合

A ( x ) = ∑ i = 0 ∞ 2 i x i = 1 1 − 2 x \begin{aligned}A\left( x\right) =\sum ^{\infty }_{i=0}2^{i}x^{i}\end{aligned}=\dfrac{1}{1-2x} A(x)=i=02ixi=12x1
B ( x ) = ∑ i = 0 ∞ 2 6 i x i = 1 1 − 26 x \begin{aligned}B\left( x\right) =\sum ^{\infty }_{i=0}26^{i}x^{i}\end{aligned}=\dfrac{1}{1-26x} B(x)=i=026ixi=126x1

C ( x ) = A ( x ) + B ( x ) C(x)=A(x)+B(x) C(x)=A(x)+B(x) C ( x ) C(x) C(x)表示全体 01 01 01串与全体字母的并集
C ( x ) C(x) C(x) x i x^i xi项的系数表示长度为 i i i 01 01 01串与字符串有多少

D ( x ) = A ( x ) B ( x ) D(x)=A(x)B(x) D(x)=A(x)B(x) D ( x ) D(x) D(x)表示 01 01 01串与字符串拼接出的串(前面是 01 01 01串,后面是字符串)
D ( x ) D(x) D(x) x i x^i xi项的系数表示长度为 i i i的拼接出的串有多少
其中某串长度可以为0

个人理解

我们发现上面的例题中的 D D D如果我们不考虑多项式
自己暴力的去算,也有这样的公式
∑ i + j = n a i b j \begin{aligned}\sum_{i+j=n}a_ib_j\end{aligned} i+j=naibj
其中 a i a_i ai表示长度为 i i i 01 01 01串有多少种, b j b_j bj表示长度为 j j j的字符串有多少种
然后我们可以发现长度 i + j i+j i+j的答案会由 i i i j j j项得到,再发现其与指数乘法有相似之处,即 x i x j = x i + j x^ix^j=x^{i+j} xixj=xi+j,之后就想到将答案存为其系数, x i x^i xi表示实际意义,于是就可以用多项式来解决问题,因为多项式可以 F F T FFT FFT优化,比暴力快很多
(我觉得生成函数可能就是这么来的…)


指数生成函数(EGF)

引入

有时我们需要考虑带标号的组合对象,比如图
n n n个点的标号图,顶点的标号恰好为 1 ∼ n 1\sim n 1n

带标号对象的拼接

将两个对象 a ; b a;b a;b拼接起来, ∣ a ∣ = n , ∣ b ∣ = m |a|=n,|b|=m a=nb=m

  • 无标号时,只有一种方法
  • 带标号时,规定拼接时拼接对象内部相对标号顺序不变,而互相的标号
    可以改变,则有 C n + m n ( ( n + m n ) ) C_{n+m}^{n}(\begin{pmatrix} n+m \\ n \end{pmatrix}) Cn+mn((n+mn))种拼接方法
    因为只要考虑前 a a a中的 n n n个用了哪些标号,剩下的 m m m个给 b b b中的 m m m个,答案唯一,而对象内部相对标号顺序不变,所以得到的标号如何分配也是唯一的
    eg.
    213 , 21 213,21 213,21(每个数字是一个标号)拼接,有 10 10 10种方法
    数字表示分配的标号
    435 , 21 ∣   425 , 31 ∣   325 , 41 ∣   324 , 51 ∣   415 , 32 435,21|\ 425,31|\ 325,41|\ 324,51|\ 415,32 435,21 425,31 325,41 324,51 415,32
    315 , 42 ∣   314 , 52 ∣   215 , 43 ∣   214 , 53 ∣   213 , 54 315,42|\ 314,52|\ 215,43|\ 214,53|\ 213,54 315,42 314,52 215,43 214,53 213,54
    如第一种方案 435 435 435对应的 231 231 231相对标号顺序不变, 31 31 31对应的 21 21 21相对标号顺序也不变

定义

对于带标号组合对象组成的集合 A A A,定义
A ( x ) = ∑ i = 0 n A i x i i ! \begin{aligned}A\left( x\right) =\sum _{i= 0}^nA_{i}\dfrac {x^{i}}{i!}\end{aligned} A(x)=i=0nAii!xi
A A A的指数生成函数

运算

有两类组合对象 A A A B B B

  • 定义 C C C A A A B B B的并集
    C ( x ) = A ( x ) + B ( x ) , O ( n ) C(x) =A(x) +B(x),O(n) C(x)=A(x)+B(x)O(n)计算
  • 定义 D D D A A A B B B的笛卡尔积,也即 D D D中每个元素 d d d都是 A A A中某元素 a a a B B B中某元素 b b b拼成的二元组 ( a , b ) (a,b) (a,b),其大小 ∣ d ∣ |d| d 定义为 ∣ a ∣ + ∣ b ∣ |a|+|b| a+b
    D ( x ) = A ( x ) B ( x ) D(x) =A(x)B(x) D(x)=A(x)B(x) F F T FFT FFT乘法 O ( n l o g n ) O(nlogn) O(nlogn)计算

没错,就是复制上面的内容
对于 D ( x ) D(x) D(x)
D ( x ) = ∑ i + j = n A i B j ( i + j ) ! i ! j ! \begin{aligned}D(x)=\sum _{i+j=n}A_{i}B_{j}\dfrac {\left( i+j\right) !}{i!j!}\end{aligned} D(x)=i+j=nAiBji!j!(i+j)!
D ( x ) n ! = ∑ i + j = n A i i ! B j j ! \begin{aligned}\dfrac {D(x)}{n!}=\sum _{i+j=n}\dfrac {Ai}{i!}\dfrac {B_{j}}{j!}\end{aligned} n!D(x)=i+j=ni!Aij!Bj
所以乘法运算成立

个人理解

如引入中的问题
用一般生成函数来求解
D ( x ) = A ( x ) B ( x ) = ∑ i + j = n n A i ⋅ B j ( n i ) \begin{aligned}D\left( x\right) =A\left( x\right) B\left( x\right) =\sum ^{n}_{i+j=n}A_{i}\cdot B_{j}\begin{pmatrix} n \\ i \end{pmatrix}\end{aligned} D(x)=A(x)B(x)=i+j=nnAiBj(ni)
最后又化简成

D ( x ) n ! = ∑ i + j = n A i i ! B j j ! \begin{aligned}\dfrac {D(x)}{n!}=\sum _{i+j=n}\dfrac {Ai}{i!}\dfrac {B_{j}}{j!}\end{aligned} n!D(x)=i+j=ni!Aij!Bj
于是我们就弄出一个指数生成函数方便运算且省去求组合数

以下 A A A为生成函数

生成序列(seq)

如字面意思,要生成一个序列
序列的顺序是确定的
s e q ( A ) = ∑ i = 0 ∞ A i = 1 1 − A \begin{aligned}seq\left( A\right) =\sum ^{\infty }_{i=0}Ai=\dfrac {1}{1-A}\end{aligned} seq(A)=i=0Ai=1A1

生成集合(set)

如字面意思,要生成一个集合
集合的顺序是无关紧要的,所以要除以全排列

s e t ( A ) = ∑ i = 0 ∞ A i i ! = e A \begin{aligned}set\left( A\right) =\sum ^{\infty }_{i=0}\dfrac{A^i}{i!}=e^A\end{aligned} set(A)=i=0i!Ai=eA

最后一步是因为该式子符合 e x e^x ex的泰勒展开
关于泰勒展开可看我的该篇博客泰勒公式于牛顿迭代

如有哪里讲得不是很明白或是有错误,欢迎指正
如您喜欢的话不妨点个赞收藏一下吧

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值