生成函数

生成函数简介

生成函数 ( ext{(generating function)}),又称母函数,是一种形式幂级数,其每一项的系数可以提供关于这个序列的信息。
by wiki

用人话来说生成函数就是把一个序列变成了一个函数。

一个形如 (F(x) = sum_{n > 0}{a_n imes x^n}) 的函数可以理解为他是一个每一项分别为 (a_n) 的序列。

普通生成函数

重新引用上面的定义 (F(x) = sum_{n > 0}{a_n imes x^n})

这个 (n) 的定义域是到正无穷的,因为在序列的意义下,不存在的项的系数即为 (0),代回带函数里面也不影响。

关讲过于抽象,举几个栗子(我们定义 (a) 为序列, (F(x)) 为它的生成函数)。

  • (a = [1, 2, 3])(F(x) = 1 + 2 imes x + 3 imes x ^ 2)

  • (a = [1, 1, 1 …])(F(x) = sum_{n >= 0}{x ^ n})

  • (a = [1, 2, 4 …])(F(x) = sum_{n >= 0}{2 ^ n imes x ^ n})

  • (a = [1, 3, 5 …])(F(x) = sum_{n >= 0}{(2 imes x + 1) imes x ^ n})

通过上面的很多栗子,相信大家可以发现函数每一项的系数就是序列的每一项的值。

接下来有一些很 (naive) 的运算法则。

由于序列之间的运算是项项相对应的。

所以数字之间满足的运算法则,在生成函数里面也一样适用。

运算法则

1.加法运算:

考虑对于 (2) 个普通的生成函数,他们的生成函数为 (F(x))(G(x))

(F(x) + G(x) = sum_{(a_n + b_n)} imes x ^ n)

这样 (F(x) + G(x)) 是序列 (a_n + b_n) 的普通生成函数。

2.乘法运算:

考虑对于 (2) 个普通的生成函数,他们的生成函数为 (F(x))(G(x))

(F(x) imes G(x) = sum_{x ^ n} sum_{i = 0}^{n}{a_i imes b_{n - i}})

这样 (F(x) imes G(x)) 是序列 (a_n imes b_n) 的普通生成函数。

但是写太多 (sum) 会显得整个柿子特别的丑陋,所以就有了封闭形式。

(a = [1, 1, 1 …]) 为例,它的生成函数是 (F(x) = sum_{n >= 0}{x ^ n})

那么我们进一步化简可以得到 (F(x) * x + 1 = F(x))

移项可得 : (F(x) = frac{1}{1 - x})

就不再一一赘述,如果想要进一步理解的可以看 wiki 上的小练习,上面从从易到难,有求导,二项式定理,数学归纳法……运用。

斐波拉契数列

有一个非常著名而且经典的序列叫斐波拉契数列。

他的递推式是这个样子的:(f(x) = f(x - 1) + f(x - 2))

咋一看这个式子就感觉它很不好推是吧,但是我们有项数之间的数量关系对吧,那么就可以很容易的推出它的封闭形式。

(f(x) = x imes f(x) + x ^ 2 imes f(x) - a_0 imes x + a_1 imes x + a_0)

这个柿子可以理解为把 (f(x)) 右移一位和右移两位的结果相加,并且补上那些移项所消失的项。

即:(f(x) = frac{x}{1 - x - x ^ 2})

我们可以把封闭形式暴力分解:

(f(x) = frac{x}{1 - x - x ^ 2} = frac{x}{(1 - frac{1 - sqrt{5}}{2}) x imes (1 - frac{1 + sqrt{5}}{2}) x})

(u = frac{1}{1 - frac{1 - sqrt{5}}{2}}, v = sqrt{5})

那么原始可以化简为:(frac{x}{u imes (u + v)} = frac{u}{v} imes (frac{1}{u} - frac{1}{u + v}))

带回即可得 : (frac{x}{(1 - frac{1 - sqrt{5}}{2}x) imes (1 - frac{1 + sqrt{5}}{2}x)})

化简可得 : (frac{1}{sqrt{5}} imes ((frac{1 + sqrt{5}}{2}) ^ n) - (frac{1 - sqrt{5}}{2}) ^ n))

也就是我们常见的形式。

封闭形式转化为展开形式

先咕着

一些例题

洛谷P2000 拯救世界

题解:

经典的生成函数入坑题。

对于题目里描述的 (10) 种召唤方法,我们分别计算他的封闭形式并相乘,然后转化为展开形式并且求第 (n) 的系数就行了。

( ext{kkk})

  • 金:(1 + x ^ 6 + x ^ {12} … = frac{1}{1 - x ^ 6})

  • 木:(1 + x ^ 2 + … + x ^ 8 = frac{1 - x ^ {10}}{1 - x})

  • 水:(1 + x ^ 2 + … + x ^ 4 = frac{1 - x ^ 5}{1 - x})

  • 火:(1 + x ^ 4 + x ^ 8 + … = frac{1}{1 - x ^ 4})

  • 土:(1 + x ^ 2 + … + x ^ 6 = frac{1 - x ^ 6}{1 - x})

( ext{lzn})

  • 金:(1 + x ^ 2 + x ^ {4} … = frac{1}{1 - x ^ 2})

  • 木:(1 + x = frac{1 - x ^ {2}}{1 - x})

  • 水:(1 + x ^ 8 + x ^ 16 = frac{1}{1 - x ^ 8})

  • 火:(1 + x ^ 10 + x ^ 20 + … = frac{1}{1 - x ^ 10})

  • 土:(1 + x ^ 2 + x ^ 3 = frac{1 - x ^ 4}{1 - x})

很多项都可以约掉,最后得到的就是:(frac{1}{(1 - x) ^ 5})

这个东西要怎么展开呢?

(frac{1}{(1 - x) ^ 5} = (frac{1}{1 - x}) ^ 5 = C_{n + 4} ^ {4} = (n + 1) imes (n + 2) imes (n + 3) imes (n + 4) / 24)

这个东西要用高精或者 ( ext{NTT}) ,当然 ( ext{ruby}) 还是更香的。

原文地址:https://www.cnblogs.com/Flash-plus/p/14196938.html