常生成函数
概述
在数学中,某个序列\(a_n\)的母函数(又称生成函数)是一种形式幂级数,其每一项的系数可以提供关于这个序列的信息。使用母函数解决问题的方法称为母函数方法。
序列\(a\)定义为形式幂级数有以下形式
例如:
- 序列\(a = <1, 2, 3>\)的常生成函数是\(1 + 2x + 3x^3\)
- 序列\(a = <1,1,1,1...>\)的常生成函数是\(\sum_{n \ge 0}x^n\)
- 序列\(a = <1, 3, 5, 7...>\)的常生成函数是\(\sum_{n \ge 0}(2n+1)x^n\)
常生成函数常用于多重集选择组合问题
应用
常生成函数通常解决以下问题:
给定非负整数\(x_1,x_2,x_3...,x_k\),求\(x_1+x_2+x_3...+x_k=n\)有多少组解
以上述问题为例,我们隐式规定了\(0\le x_i \le n\),若我们为每个变量构造一个生成函数,则对于第i个数,它的生成函数为\(f(x)=1+x+x^2+x^3...+x^n\),
若将所有的生成函数相乘,则\(g(x)=(1+x+x^2+...+x^n)^k\)的\(x^n\)的系数就是所求答案
这里给出几个常用替换式:
- \(1+x+x^2+x^3...+x^n=\frac{1}{1-x}\)
- \(\frac{1}{(1-x)^k}=\sum_{n\ge0}C_{n+k-1}^{k-1}x^n\)
例1.背包
题目描述
tacmon准备带大家去YZ一日游,他要带很多东西,一共有以下8种: 肥宅快乐水,鸡腿,鸡翅,鸡块,鸡汤,鸡蛋,大盘鸡,啤酒鸡 ...emm...真香。
他要带得东西太多了,所以你理所当然的要帮他算带N个东西的方案数啦。 另外,在tacmon的眼里,所有的东西都是以“个”为单位的,而且每一种物品都有一些奇怪的限制。
- tacmon最多会带1个肥宅快乐水(当然可以不带)
- 他也认为大盘鸡和啤酒鸡太贵了,所以这两个东西他分别最多带2个和3个
- 总所周知,鸡翅总是要成对出现的
- tacmon认为偶数个鸡汤不好分,所以他准备带奇数个
- 鸡块实在太好吃了,tacmon认为一个人一定会吃4个,所以他一定会带4的倍数个鸡块
- tacmon最讨厌吃鸡腿了,所以他最多带一个鸡腿
- 而鸡蛋,他准备带三的倍数个...
良心的tacmon觉得他的限制有点小多,所以他要好心的告诉大家,除了鸡汤,其他的东西不带也是符合要求的。
输入格式
一行一个整数N,表示tacmon要带的物品个数
输出格式
一行一个整数,即答案对\(10^9+7\)取模的结果。
数据范围
\(1 \le N \le 10^{18}\)
输入样例
1 |
|
输出样例
1 |
|
题解
本题使用容斥也能通过,这里讲解生成函数的做法,对于每一种食物,可以构造其生成函数,将八种食物累乘得到多项式\(G(x)\),\([x^n]G(x)\)就是答案,接下来是各类食物对应生成函数的化简:
- 肥宅快乐水:\(1+x=\frac{1-x^2}{1-x}\)
- 大盘鸡:\(1+x+x^2=\frac{1-x^3}{1-x}\)
- 啤酒鸡:\(1+x+x^2+x^3=\frac{1-x^4}{1-x}\)
- 鸡翅:\(1+x^2+x^4+...=\frac{1}{1-x^2}\)
- 鸡汤:\(x+x^3+x^5...=\frac{x}{1-x^2}\)
- 鸡块:\(1+x^4+x^8...=\frac{1}{1-x^4}\)
- 鸡腿:\(1+x=\frac{1-x^2}{1-x}\)
- 鸡蛋:\(1+x^3+x^6...=\frac{1}{1-x^3}\)
因此\(G(x)=\frac{x}{(1-x)^4}=x\times\sum_{n\ge0}C_{n+3}^{3}x^n=\sum_{n\ge 1}C_{n+2}^{3}x^n\)
于是\([x^n]G(x)=C_{n+2}^{3}=\frac{(n+2)(n+1)(n)}{6}\)
注意取模就能通过本题
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
例2.Devu and Flowers
题解
构造出每种花的生成函数\(F^i(x)=1+x+x^2...+x^{f(i)}=\frac{1-x^{f(i)+1}}{1-x}\)
累乘后\(G(x)=\prod_{i\le n}F(i)=\frac{\prod_{i\le n}(1-x^{f(i)+1})}{(1-x)^n}\)
最后答案为\([x^s]G(x)\)
若令\(A(x)=\prod_{i\le n}(1-x^{f(i)+1})\),\(B(x)=\frac{1}{(1-x)^n}=\sum_{i\ge 0}C_{i+n-1}^{n-1}x^i\)
则答案是由\(A(x)和B(x)\)共同得出
发现n很小,因此我们可以二进制枚举\(A(x)\)的每一项,复杂度为\(O(2^n)\),若此时枚举到的指数为\(k\),则我们只需要求\([x^{s-k}]B(x)\)即可,容易得到这一项的值为\(C_{s-k+n-1}^{n-1}\)
对于取模且\(a,b\)很大时,我们考虑lucas定理
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
|
例3.[CEOI2004] Sweets
题解
本题和上一题很相似,不同的是总数是一段区间,若枚举总数则复杂度达到了\(O((b-a)n2^n)\),显然超时,因此需要优化
\(res = \sum_{i=a}^{i=b}\sum_{j}([x^j]A(x))C_{i-j+n-1}^{n-1}\)
\(res\)的得出同上题
接下来讲讲怎么优化
变更计算顺序,将枚举i变为枚举j
\(res=\sum_{j}([x^j]A(x))\sum_{i=a}^{i=b}C_{i-j+n-1}^{n-1}\)
我们知道\(C_{a+1}^{b+1}=C_{a}^{b+1}+C_{a}^{b}\)
因此原式可化简为
\(res=\sum_{j}([x^j]A(x))(C_{b-j+n}^{n}-C_{max(a,j)-j+n-1}^{n})\)
\(max(a,j)\)是因为当\(j>a\)时并未是无意义,这一部分的答案也要被记录
接下来就是另一个问题了
本题的模数是2004,没有逆元,扩展卢卡斯定理可以做,但这里有个小技巧
我们发现\(n\)只有10,而组合数计算时的分母是\(n!\),因此我们可以在求组合数时令分子计算时对\(2004 \times n!\)取模,最后在除以分母
这样这道题就被完美解决了
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
|