生成函数

生成函数用于解决一些计数问题,其运用的一个非常重要的工具是形式幂级数。
形式幂级数中,各项的系数代表方案数,各项的幂次代表个数。

常生成函数 (Ordinary Generating Function)

比如有四种水果:
苹果的个数是偶数:\(1+x^2+x^4+x^6+x^8+...=\frac{1}{1-x^2}\)
香蕉的个数是 \(5\) 的倍数:\(1+x^5+x^{10}+x^{15}+x^{20}+...=\frac{1}{1-x^5}\)
橘子的个数至多 \(4\) 个:\(1+x+x^2+x^3+x^4=\frac{1-x^5}{1-x}\)
梨的个数至多 \(1\) 个:\(1+x\)
把所有的项目乘起来:
\(\frac{1}{1-x^2}\frac{1}{1-x^5}\frac{1-x^5}{1-x}(1+x)=\frac{1}{(1-x)^2}=\sum \binom{i+1}{i}x^i\)
最后一步可以这样理解:
\(\frac{1}{(1-x)^2}=\frac{1}{1-x}\frac{1}{1-x}=(1+x+x^2+x^3+x^4+...)(1+x+x^2+x^3+x^4+...)\)
对于特定幂次 \(i\),第一个括号可以取 \(1 \sim x^i\),后一个括号可以相应取 \(x^i \sim 1\),共计 \((i+1)\) 对。
\(\frac{1}{(1-x)^2}=\sum (i+1)x^i\)

推广到一般的情形:
\(\frac{1}{(1-x)^k}=(1+x+x^2+x^3+x^4+...)^k\)
要求某个特定幂次 \(i\) 的系数,要将 \(i\) 分给各个括号,其实就是插板法,将 \(i\) 个球分成 \(k\) 组,每组可以取 \(0\),故结果为 \(\binom{n+k-1}{i}\)
\(\frac{1}{(1-x)^k}=\sum \binom{n+k-1}{i}\)

对于一些比较复杂的计数问题,如果整个系统由多个部分组成,每个部分又可以比较方便地写为形式幂级数,而总体方案等于各个部分方案相乘的话,就可以用生成函数方式求解。
计算中如果项数比较多,可能会需要用到 NTT。

指数生成函数 (Exponential Generating Function)

接上面的例子,有时候我们不仅需要考虑选了哪些水果,还需要考虑水果的顺序。
假定选了 \(2\) 个苹果 \(5\) 个香蕉 \(3\) 个橘子 \(1\) 个梨,按照上面生成函数的做法,最终的结果并不会考虑顺序问题。只会由 \(x^2x^5x^3x^1=x^{11}\) 为选取 \(11\) 个水果贡献 \(1\) 个方案。
而实际上,如果考虑水果的顺序,这一种数量方案其实对应有 \(\frac{11!}{2!5!3!1!}\) 种不同的顺序。
简单理解就是 \(11\) 个水果有 \(11!\) 种排列,但是同种水果内部的排列是重复计算的,所以重复计算了 \(2!5!3!1!\) 倍。
注意到,只要用了 \(2\) 个苹果就会在分母出现 \(2!\),而与总构成无关;同理只要用了 \(5\) 个香蕉,分母就会出现 \(5!\)。以此类推。因此我们在写生成函数的时候,直接为各个幂次配上一个相应阶乘的分母即可。
这样,之前的生成函数可以写为:
苹果的个数是偶数:\(1+\frac{x^2}{2!}+\frac{x^4}{4!}+\frac{x^6}{6!}+\frac{x^8}{8!}+...\)
香蕉的个数是 \(5\) 的倍数:\(1+\frac{x^5}{5!}+\frac{x^{10}}{10!}+\frac{x^{15}}{15!}+\frac{x^{20}}{20!}+...\)
橘子的个数至多 \(4\) 个:\(1+\frac{x}{1!}+\frac{x^2}{2!}+\frac{x^3}{3!}+\frac{x^4}{4!}\)
梨的个数至多 \(1\) 个:\(1+\frac{x}{1!}\)
原则上,只需要直接做多项式卷积就能得到结果了。假定要求的是总水果数在 \(100000\) 以内的各个结果,即 \(x^{100000}\) 及更低幂次的系数,则前两个无限项的都只需要预处理出 \(x^{100000}\) 以内的系数,然后做卷积即可。后两个本身项数很少,算出各项系数做卷积即可。

但是如果前两类形式的式子很多,多次卷复杂度过高,可以直接写成指数形式。在合适的时候运算会非常简单。
注意指数函数的泰勒展开
\(e^x=1+\frac{x}{1!}+\frac{x^2}{2!}+\frac{x^3}{3!}+\frac{x^4}{4!}+...\)
\(e^{-x}=1-\frac{x}{1!}+\frac{x^2}{2!}-\frac{x^3}{3!}+\frac{x^4}{4!}+...\)
与前述两个无限项非常类似。
实际上,我们把两个式子加起来除以 \(2\) 即得到:
\(\frac{e^x+e^{-x}}{2}=1+\frac{x^2}{2!}+\frac{x^4}{4!}+...\)
上式即为苹果的表达式。
此外,我们把两个式子相减除以 \(2\) 即得到:
\(\frac{e^x-e^{-x}}{2}=\frac{x}{1!}+\frac{x^3}{3!}+\frac{x^5}{5!}+...\)
此即一个水果必须选奇数个的表达式。
此即指数生成函数的由来,其形式就是指数函数的泰勒展开。
对于第二个 \(5\) 倍数的生成函数,也是可以写成指数函数的,但是比较复杂。

如果是多个无限项的水果组合,那么全都可以写作指数函数,之后就可以很简单地按泰勒展开处理。
比如:
苹果的个数是偶数:\(1+\frac{x^2}{2!}+\frac{x^4}{4!}+\frac{x^6}{6!}+\frac{x^8}{8!}+...=\frac{e^x+e^{-x}}{2}\)
香蕉的个数是偶数:\(1+\frac{x^2}{2!}+\frac{x^4}{4!}+\frac{x^6}{6!}+\frac{x^8}{8!}+...=\frac{e^x+e^{-x}}{2}\)
橘子的个数是奇数:\(\frac{x}{1!}+\frac{x^3}{3!}+\frac{x^5}{5!}+\frac{x^7}{7!}+\frac{x^9}{9!}+...=\frac{e^x-e^{-x}}{2}\)
梨子的个数是奇数:\(\frac{x}{1!}+\frac{x^3}{3!}+\frac{x^5}{5!}+\frac{x^7}{7!}+\frac{x^9}{9!}+...=\frac{e^x-e^{-x}}{2}\)
草莓的个数是任意:\(1+\frac{x}{1!}+\frac{x^2}{2!}+\frac{x^3}{3!}+\frac{x^4}{4!}+\frac{x^5}{5!}+...=e^x\)

总方案数为:\((\frac{e^x+e^{-x}}{2})^2(\frac{e^x-e^{-x}}{2})^2e^x \\ =\frac{e^{2x}+e^{-2x}+2}{4}\frac{e^{2x}+e^{-2x}-2}{4}e^x=\frac{(e^{2x}+e^{-2x})+2}{4}\frac{(e^{2x}+e^{-2x})-2}{4}e^x=\frac{e^{4x}+e^{-4x}+2-4}{16}e^x=\frac{e^{5x}+e^{-3x}-2e^x}{16}\)

要求特定项的系数,只需要按泰勒展开,然后写出各项的系数即可。
\(\frac{e^{5x}+e^{-3x}-2e^x}{16}=\frac{1}{16}(\sum \frac{(5x)^i}{i!}+\frac{(-3x)^i}{i!}-2\frac{(x)^i}{i!})\)
对于某个特定幂次的系数,有:
\([x^n]\frac{e^{5x}+e^{-3x}-2e^x}{16}=\frac{1}{n!16}(5^n+(-3)^n-2)\)
上述计算仅考虑了同种水果内部去重,整体的排列还没算,所以需要乘以 \(n!\),最终结果为
\([x^n]n!\frac{e^{5x}+e^{-3x}-2e^x}{16}=\frac{1}{16}(5^n+(-3)^n-2)\)

posted @ 2026-06-10 00:22  qwynick  阅读(8)  评论(0)    收藏  举报