补一发生成函数 还挺有趣的。。生推各种通项公式(~~好像有的需要泰勒展开?~~
首先我们定义一个数列${a_1,a_2,a_3,a_4,a_5,a_6....}$考虑用函数表达一下这个数列。
则有 $f(x)=a_1+a_2x+a_3x^2+a_4x^3+a_5x^4+a_6x^5+...$
好像没啥大用 那从一个小引子开始吧.
比如说 数列a这类物品选i件的方案数 例:a={1,1,1};只能选不大于两件。
无限长$b = {1, 0, 0, 1, 0, 0, 1, 0, 0, 1...}$表示B类物品只能选3的倍数件的各个方案数。
那么把$f(x)=1+x+x^2$和$g(x)=1+x^3+x^6+x^9+...$乘起来第i项的系数就表示a,b两种物品共选i件的方案数..
可以FFT,就nlogn啦...(当然不这样表示你也是可以看出要FFT的...
此时研究一个特殊的生成函数:$1+x+x^2+x^3+...$当$xin (-1,1)$时生成函数又为$frac{1}{1-x}$
等比数列求一发和即可。
那还有生成函数$1+3x+6x^2+10x^3+15x^4+...$这个东西求和之后为$frac{1}{(1-x)^3}$
推广一下$frac{1}{(1-x)^k}$的生成函数的数列为$sum_i^infty C_{i+k-1}^{k-1}x^i$
隔板法的简单应用..
我说到这里你一定还是很蒙蔽对吧,因为 我根本就没有说明生成函数的定义。
什么是生成函数:也叫母函数 是组合数学中尤其是计数方面的一个重要理论和工具。
生成函数有两种 普通型生成函数和指数型生成函数 运用这种数学方法可以对程序的效率与速度有很大的提升。
大体上解决问题时 我们利用函数表达一个数列 然后进行化简求和等用一个非常短的式子来代替一个数列。
然后进行数列相乘 进行快速运算的时候我们可以直接利用生成的这个函数来进行运算。
最后展开这个数列 然后求出需要的 第n项的系数即为答案。
展开的时候 我们回望来时的路 展开即可。
我想 生成函数的实质 是从代数->函数->表达式->通项这个过程过来的吧。
上题练练?
[bzoj 3028食物](https://www.lydsy.com/JudgeOnline/problem.php?id=3028)
直接暴力背包显然不可做 组合计数能让你起飞。
生成函数一发 化简式子还是挺简单的 最后的式子为 $frac{x}{(1-x)^4}$
再展开回去 发现 第n项的系数为 C(n+2,3).n过大且p为10007 小 而且还是质数 使用卢卡斯定理即可.
卢卡斯定理:C(n,m)=C(n/p,m/p)%p$cdot$C(n%p,m%p)%p;
恭喜你成功入门生成函数 23333
再来题目:
[luogu 2000拯救世界](https://www.luogu.com.cn/problem/P2000)
这道题目首先注意的是 不要读错题 有两种方法 意味着 各种神石的使用方法都有两种但是这两种也是分开计算的。
n块神石每块可以只能当作一种来用。很多限制条件 让我利用生成函数了。
列出式子+化简整个过程非常的简单。最后的式子为$frac{1}{(1-x)^5}$
不难发现我们要求得是 C(n+4,4); 再化简一下 (n+4)(n+3)(n+2)(n+1)/24
3次NTT即可...ps:第一次用NTT写高精 还怪好写的。。。
再来一道:
[luogu 6078糖果 CEOI 2004](https://www.luogu.com.cn/problem/P6078)
答案要对2004取模但是题目上好像没写...列出来生成函数 发现后面还有一坨东西。
后面的东西考虑暴力展开 最多有2^n方项 和前面的相乘 显然我们有p$cdot$...一堆可以通过基础的组合数变形的到 C(n+a-y,n);
于是乎复杂度为$2^ncdot n$.值得一提的是 求组合数的时候不需要对n!取逆元这样不方便。
因为n!和mod可能是不互质的 别提费马小定理了 连扩展欧几里得都用不了 不存在逆元.
解决方法:我们让mod$cdot$n! 让答案对这个东西取模 最后再除以n!即可得到答案.
当然你真的不太会的话可以尝试约分不过复杂度要高一丢丢.
简单说一下原理:大体上 我们取模后一般是质因子有可能被膜掉了考虑答案里面有多少个n!如果恰好为mod的整数倍说明不管怎么搞都是0.
如果没有的话 那肯定还剩下若干个n!除一下得到答案. 接下来是指数型生成函数简称EGF 和普通型生成函数唯一的区别是 配系数的时候 多除以了阶乘这是为了简便的解决排列问题而特意设立的. 其他的我也没什么好说网上都有下面开始习题时间. [bzoj3456城市规划](https://www.lydsy.com/JudgeOnline/problem.php?id=3456)
这道题我用分治FFT做到自闭...
考虑指数生成函数怎么做?为什么会是指数生成函数呢?下面围绕这两个问题进行讨论。注意下面都是讨论有标号的情况。
设 G(x) 表示一张任意无向图的指数生成函数。
那么其中第i项的系数为 $2^{C_{i}^{2}}$
设 F(x) 表示一张无向联通图的指数生成函数.设fi表示i个点的无向联通图的方案数。
那么显然F(x)的第i项的系数为$f_i$.
考虑组合意义 那么显然了 G(x)=e^{F(x)} 那么求F(x) 对G取In即可。
我不太清楚。。按照我的理解 对于i这个系数 由i个F(x)相乘得到的对应的系数为G的系数。
为什么会这样 考虑到 由若干个连通块形成 所以有标号 所以每次选都存在方案数而对于同一个集合内的东西又无顺序可言所以这样是正确的。
遇到了一道非常好的题目 尽管脑壳有点疼..
[CF891E](https://www.luogu.com.cn/problem/CF891E)
我觉得算是一道质量很高 比较有难度的题目,(凡是期望题我tm的都不会做 自闭了.
每次随机一个值减一 答案增加其他值得乘积 求答案的期望...
我们不可能模拟整个局面算出来概率及答案 考虑初始整个局面的值为$Pi_{i=1}^{n}a_i$
某个值减一后局面的值变成了$(a_x-1)Pi_{i=1,i ot =x}^na_i$答案增加的量$Pi_{i=1,i ot=x}^{n}a_i$
我们发现两个局面做差即为答案的增加量 进行k次当然也就意味着初始局面减去最终局面。
但是我们如何求出最终局面的期望呢?
期望=概率*结果。概率为 $frac{1}{n^k}$这样我们只需要对结果求和就可以了。
考虑一下结果是什么 考虑每个位置最后被减去的数字为$b_i$那么显然有$sum_{i=1}{n}b_i=k$
考虑到这种局面出现的次数(因为刚才是$n^k$所以每种局面可能会在这种情况之下出现多次。
假设每次选择都是不同的$k!$最后再除以相同时候的方案数那么出现的次数为$frac{k!}{Pi_{i=1}^{n}b_i!}$
对于这种局面的贡献为 $Pi_{i=1}^{n}(a_i-b_i)$
写一下总式子$E=frac{1}{n^k}sum_{sum b_i=k}frac{k!}{Pi_{i=1}^{n}b_i!}Pi_{i=1}^{n}(a_i-b_i)$
简单变换一下$E=frac{1}{n^k}sum_{sum b_i=k}k!Pi_{i=1}^{n}frac{a_i-b_i}{b_i!}$
写到这里我们的EGF已经呼之欲出了 因为有条件$sum b_i=k$和$frac{k!}{Pi_{i=1}^{n}b_i!}$
我们对于每个元素列出来其EGF那么这两个条件就可以轻松的满足。
那么对于一个元素的EGF $F_s(x)=sum_{i=0}^{infty}frac{(a_s-i)x^i}{i!}$表示选择减掉i个数时的答案
对面对于每个元素的EGF相乘 x^k的系数即为刚才上式的答案.
设$[x^k]f(x)$表示多项式f(x)的$x^k$项的系数.
原式=$frac{k!}{n^k}Pi_{i=1}^{n}sum_{j=0}^{infty}frac{a_j-j}{j!}x^j$
化简一波 $frac{k!}{n^k}Pi_{i=1}^{n}sum_{j=0}^{infty}(frac{a_j}{j!}-frac{j}{j!})x^j$
关注与后面的最后的式子当j==0时此项为0 当j不为0的时候j和j!进行约分。
所以上式为 $frac{k!}{n^k}Pi_{i=1}^{n}sum_{j=0}^{infty}(frac{a_jcdot x^j}{j!}-xfrac{x^j}{j!})$
用泰勒展开式进行展开$frac{k!}{n^k}Pi_{i=1}^{n}(a_ie^x-xe^x))$
$frac{k!}{n^k}e^{nx}Pi_{i=1}^{n}(a_i-x)$
最后的式子可以暴力展开长度不超过n 每次乘法复杂度O(n)
当然可以考虑分治求最后的那一项 不断分治下去 在每一层做FFT.复杂度nlogn^2
至于那个$e^{nx}$这个东西也很好搞再变回去对于某个系数我们算对应的系数即可.
总复杂度 $n^2$...(这个时候写刚才的FFT确实很麻烦 估计心态会爆炸...
有一个坑点是 这里我们的EGF不是直接生成的 可以理解为我们先生成了OGF 由于下面还要除以一波$b_i$
所以形成了EGF 我们利用EGF的性质解题 最终还原成OGF 所以最后还是得除以一下!。
遇到几种复合OGF函数的题目不太理解..然后走法都是要多项式exp 靠 我不会多项式exp 题解上说要求导。 全班估计只有我一个人不会求导吧...不学了自闭了
[TJOI2015概率论](https://www.luogu.com.cn/problem/P3978)
这道题考验的估计使我们的爆搜能力和发现规律的能力。
因为看起来是要推式子的题目 很难列出来生成函数。。
同时也很难化简下去 所以这里不讲这种方法,经过我们的打表发现 $g_n=nf_{n-1}$其中g数组表示答案f数组表示二叉树的个数。
考虑证明这个东西我想几次都无法将其证明出来 而在_rqy的题解之中却说道非常的简单我觉得这很受打击啊。。
我们考虑对于一颗n个点的二叉树来说其有k个叶子节点 我们只需要求出$sum_{k}$即可。
考虑我们把这k个节点分别给去掉 那么会生成k-1个二叉树 显然我们只需要求出有多少个n-1个由这种方法生成的二叉树即可。
我们发现一个二叉树有n个位置都可以再挂一个儿子 这说明了每个二叉树有n次机会成为一个n叉树 综上可以发现这种二叉树的个数刚好为$nf_{n-1}$.
而f数组显然是卡特兰数 所以直接利用卡特兰数的通项即可。
[SDOI2017 序列计数](https://www.luogu.com.cn/problem/P3702)
题目很好懂 但是我们发现为|p这个条件没有任何的强力条件。
可以考虑dp当然我直接上生成函数了 发现是$G(x)^nmod x^p$最后系数为0的那项系数为答案。
每次都是一样的多项式相乘显然可以快速幂优化 多项式可以变成卷积 但是值得注意的是FFT掉精度 NTT可能会模掉数值 所以这里直接$p^2$暴力多好..
至少有一个质数?容斥一下完事...