生成函数的笔记
众所周知不会生成函数什么计数题都做不了。
几乎对着这篇学的,感谢苹果蓝老师给我的帮助!
只学了我觉得有必要学且我学得会的内容。
前置
多项式
暂时知道一些东西就行。
可以 \(O(n\log n)\) 卷积。
一部分柿子可以分治加卷积,\(O(n\log^2 n)\)。譬如分式求和。
泰勒展开
其实容易理解。假设 \(f(x)\) 是无穷项的幂函数的和,那 \(f(0)\) 就是常数项,\(\frac{f^{(k)}(0)}{k!}\) 就是 \(k\) 次项,那个 \(k!\) 是因为导会把指数导下来。
广义二项式
OGF
生成函数的本质,就是把一个无穷序列映射到环上。
考虑最基础的:
高阶前缀和
考虑
这里 \(I\) 是常函数,我们同时表示常函数的生成函数:\(I=\frac{1}{1-x}\)。
差分是逆运算,自然就是 \(I^{-1}\)。这里就不用 \(\mu\) 了,那个是莫反特有的。
自然有 \(k\) 阶的:
基本操作
平移
这边移动方向看作二进制哈。
左移显然就是乘 \(x\),左移 \(k\) 位就是乘 \(x^k\)。
右移就是乘 \(x^{-k}\),但是要去掉前面几项。
指数下放算子:\(\vartheta A(x)=xA'(x)=\sum_{i}ia_ix^i\)。
伸缩
单位根反演
序列通项
以斐波那契生成函数 \(F(x)=\frac{x}{1-x-x^2}\) 为例。
考虑分解成几个生成函数的解。
注意到 \(\begin{aligned}\sum_{i=0}^{\infty}n^ix^i=\frac{1}{1-nx}\end{aligned}\)。
将分母分解成两个这种形式的积,有 \(m=\phi,n=\hat{\phi}\)。
裂项:\(\begin{aligned}\frac{c}{ab}=\frac{a-b}{ab}\frac{c}{a-b}=(\frac{1}{b}-\frac{1}{a})\frac{c}{a-b}\end{aligned}\)。
后面就不多说了。
特征方程法:
所有 \(\lambda\) 都是待定系数。
数列 \(k\) 次幂和
分式形式可以分治卷积。
类似的,如果你要求 \(n\) 个数可重地选 \(k\) 个乘积的和:
不可重地:
背包问题
完全背包方案计数。即 \(n\) 件物品,第 \(i\) 件体积 \(V_i\)。
轻松有 \(Ans_k=[x^k]\prod_{i=1}^n\frac{1}{1-x^{V_i}}\)。
乘转加和取 \(\ln\)。这种东西的 \(\ln\) 的泰勒展开我们已经熟能生巧了。
容易注意到系数加的位置是调和级数的。
当然也可以直接分治卷积。总之最后 \(exp\) 回来即可。
异或和问题
小技巧:多设一维形式幂级数 \(y\),再考虑消除,譬如单位根反演。
和之积
树划分
积之和
定义一个树划分的权值是连通块大小之积,求和。
有朴素方程:
初值 \(f_{u,1}=1\)。
写成生成函数:
转移需要导数,同时维护一下。
注意到终值是 \(F_1'(1)\),所以带 \(x=1\):
小巧思做到 \(O(n)\)!
莱布尼兹公式:
多元
权值定义为两种权分别求和的积的积,然后求和。
好像要偏导……
其实差不多吧,就是两边一起导。
具体的东西学变分了再说。
常见技巧
快速多项式复合
给出 \(n\) 次多项式 \(F(x)\) 和 \(G(x)\),求 \((F\circ G)(x)\)。
幂函数
就是伸缩,直接手改。
一次函数
二项式定理拆开后可以发现大概是系数做一个差卷积。
二次函数
直接配方法,然后按顺序复合即可,与前面一致。
更高次幂多项式
太难了我只能说,好像 noshi91 做到了 \(O(nlog^2 n)\)。别学了。
特殊的分式
通用技巧是想办法拆成只含一个 \(x\) 项的柿子,然后从内导外复合。
复合分式就直接广义二项式拆开做差卷积。
指数函数(\(ae^x\))
把 \(e\) 展开了,再随手写成个生成函数随便做。咋展开后面 EGF 说。
线性算法与转置原理
线性算法就是由线性函数(可以看作将乘在向量上的矩阵)组成的算法。
那把它翻转我们显然有一个线性算法的转置算法。
众所周知每个矩阵都可以拆成初等矩阵:对换、翻倍、倍加。
那转置算法刚好就是倒过来且每个都转置。
额其中只有倍加对象交换,另外两个其实没有变。
用处似乎是求后缀转求前缀之类的,没遇到就先不说了。
q-模拟
好像就是啥柿子都带个 \(q\)。
\(q=1\) 时就是原数。
用 q-整数定义 q-阶乘和 q-组合数。
容易发现这个 q-模拟的东西都可以 \(O(n)\) 预处理。
推的方式是把生成函数拆开,\(A(qx)\) 系数 \(a_iq^i\)。
总之你把这玩意当正常的用。容易猜出 \(a_i=\binom{n+i}{i}_q\)。
其余也是类似的方法,代个 \(qx\) 即可。
类似地,有
在解递推式时一般用于处理常数项带指数时。
其它技术不太需要了吧,记个结论,q-二项式反演。和前面的那个挺像。
解析组合
用 $\mathcal{A} $ 表示。每个元素定义了大小(譬如无标号有根树的节点个数),且有限。\(\mathcal{A}_k\) 表示大小为 \(k\) 的元素集合。
可以定义生成函数 \(\mathcal{A}=\sum_{i} |\mathcal{A}_i|x^i\),其实就是每种大小的元素个数序列组成的生成函数。
也可以表示成 \(\mathcal{A}=\sum x^{|a|}\)。
对元素钦定一些运算。
笛卡尔积:元素的笛卡尔积就是视其为有序对,大小为两者之和。组合类的笛卡尔积可以组成新的组合类。
容易观察到体现在生成函数上就是卷积。
不交并:相同大小加一起。生成函数相加。
SEQ:多个元素生成的序列。
AMP:变成指定长度的组合。\(\text{AMP}_k(\mathcal{A})=A(x^k)\)。懒得在意格式了反正意思是这个意思。
群论与无标号组合构造
置换群上的组合类
\(\mathcal{A}\) 的元素 \(a\) 都可以描述成 \(\mathcal{B}\) 的有序组合(元素组成的有序对)。
称有序对大小(注意不是有序对内部元素大小和,是元素数量)为 \(a\) 的容。
\(G_k\) 表示 \(k\) 阶置换群(置换群不一定是包含全部!这不是全变换群!),\(G={G_0,G_1,G_2,...}\) 是置换群列。
\(a\) 和 \(a'\) 等价当且仅当存在 \(g\in G\) 有 \(g(a)=a'\)。
可以这么写:显然有 \(a\) 的轨道 \(G_{|a|}(a)\),那么 \(a'\) 和 \(a\) 等价就是 \(a'\in G_{|a|}(a)\)
一个轨道记号:\(\mathcal{A}/G_{\mathcal{B}}=\{G_{|a|}(a)|a\in\mathcal{A}\}\)。
其实就是所有等价类的组合类。
构造
CYC:令 \(G\) 是循环同构置换群列。
即用 \(\mathcal{A}\) 中元素组成的序列划分为无标号等价类。看作完全背包即可。
考虑计算这个组合类的生成函数。
用到了欧拉反演。
中间把 \(k\) 换成了 \(kd\)。后面那个柿子用屁股看都知道是 \(\ln\) 的泰勒展开。
如果考虑前 \(n\) 项,则复杂度是 \(O(n\log n)\) 的。
Euler/MSET:又称可重集构造。令 \(G\) 是全变换群列。
简单来说就是无标号拼合,即所谓可重集。
根据组合意义写出的组合类计算式十分的浅显易懂。
搓一下生成函数式:
看作完全背包可获得同样公式。
计算考虑先 \(\ln\) 再 \(\exp\):
\(\text{Euler}_k\) 非常难算。总之枚举集合后化柿子,复杂度分拆数。
PSET:幂集构造。
非常简单,选或不选。
中途推导和上面类似就不推了。
上面两个的逆,都考虑先 \(\ln\),然后从小到大推系数。就是先求答案较小项,再去用已知较小项更新较大项。
应用:无标号树计数
现在我们闭着屁股也能写出无标号有根树的转移了:
由于 \(\exp\) 常数大还难写,这里直接讲分治 FFT 做法。
你求 \(\ln\) 再求导,原函数导数分开看,省略一些步骤就可以分治处理。
练习
更多的练习后面再说吧……
拉格朗日反演
link。
自认为写得还行。
EGF
指数生成函数我们敬爱你口牙!
主要解决有序计数问题。
先提前给出定义式:
理解
譬如说你考虑多重集组合数。发现把阶乘的逆元直接移到系数里就可以处理所有有序问题了。最后答案乘阶乘即可。
常函数的 EGF:\(\hat{I}=\sum \frac{x^i}{i!}=e^x\)。
EGF 卷积的代数意义就是组合数卷积。求导右移积分左移。
exp 的组合意义
终于到了(流泪)!
先思考一个简单的问题:\(n\) 个有标号球丢进 \(k\) 个无标号盒子,大小为 \(i\) 的盒子方案 \(a_i\),求方案。
显然
尝试这样一件事:对所有 \(k\) 一起统计。
然后……
你在干啥?
\(\exp\) 登场!
故 EGF 下 \(\exp\) 的组合意义就是:\(n\) 划分,大小为 \(i\) 的部分带权 \(a_i\) 的积之和。
用柿子表示就是:
解析组合-有标号 DLC
又来。。。
大同小异,虽然有些不同,主要是为了契合 EGF。
笛卡尔积:序列归并。柿子一样。
SEQ:一坨序列归并。柿子一样。
PNT:无根转有根。指标下移算子。
CYC:组合类运算无区别。柿子有不同:
SET:与 \(\text{Euler}\) 一致。发现就是 exp 的组合意义,可用于任意图和连通图转换。
SUB:子结构替换。
将 \(A\) 内部的结构替换成 \(B\) 其实就是复合。
ADD 和 DEL:很简单,插入就是积分,删除就是导。
集合幂级数
之前没认真学过,稍微补一下。
注意集合、二进制、\(\mathbb{F}_2\) 的向量本质都是等价的,所以接下来会混着用,不清楚的时候就转换成你喜欢的表述吧。
朴素地说就是把集合记在了指数上,然后就可以定义与、或、异或卷积。
FWT/FMT
FFT/FWT 一类快速卷积的本质就是求值插值。
FFT 求的就是几个单位根,然后插回来。
以或卷积的 FMT 为例,我们求 \(T\in \mathbb{F}_2^{n}\) 的所有向量。
这里的求值需要仔细说明一下,毕竟集合幂级数的求值可没有那么直观。
首先 \(x^S\) 只是形式级数。可以将 \(x^S\) 看作一个 \(S\) 方向的单位向量,我们定义的运算针对两个单位向量的合成。
集合幂级数本身可以看作域,可以构造到另一个权值域的同态。
于是向量 \(T\) 的权值,可以定义为 \(T\) 导出的同态 \(\chi_T\)。事实上就是为每个单位向量赋权的操作。
由于单位向量只和 \(S\) 有关,不妨记 \(T\) 导出的 \(S\) 的权是 \(\chi_T(S)\)。
位运算是直积构造的,我们可以拆位:
外层 \(\prod\) 对应你设计的权值的乘法。
对于 \(c\),它需要对 \(s_i\) 满足同态映射,满足这个条件的函数其实基本确定了。
接下来只需要分别对每种运算解方程即可。接下来 \(s,t\) 暂时表示单个位置,简记 \(f(s)=c(t,s)\)。
- 对于 OR 运算。
- 当 \(t=0\) 时,\(f(0)=1,f(1)=0\)。
- 当 \(t=1\) 时,\(f(0)=1,f(1)=1\)。
- 综上,\(c_{OR}(t,s)=[s\le t]\)。
- 对于 AND 运算。
- 直接 \(c_{AND}(t,s)=[t\le s]\)。
- 对于 XOR 运算。
- 这个比较复杂。
- 解出来是 \((-1)^{ts}\)。
然后再把 \(c\) 的值乘起来得到 \(\chi_T\)。那么对于一个 \(T\) 的求值就是对每一位多算 \(\chi_T(S)\) 的值。
对于 OR:
对于 AND:
对于 XOR:
这里的 \(\cdot\) 是点积。
关于快速求得 FMT/FWT 的方法:
对每一位考虑贡献。然后考虑当前位的 \(0\) 对 \(1\) 的贡献。
事实上,刚才的 \(c(t,s)\) 的关系写成一个矩阵。
那只需要推导矩阵左乘的影响即可。逆变换本质是逆矩阵。
复杂度 \(O(n2^n)\)。
拓展 k-FWT
从高观点上来看就是 \(\mathbb{F}_k\) 的操作。
原来用 \(-1,0,1\) 表示的函数改用单位根即可。
子集卷积
我们从来没有规定 \(f_S\) 必须是数什么的。
事实上定义 \(f_S\) 是多项式其也构成环,所以也能用。
同样可以用形式幂级数表示多项式。这里区别 \(x\) 我们用 \(z\)。
当然如果你愿意 \(z\) 那里再套个集合幂级数也是可以的。
对于子集卷积,我们定义
定义关于集合幂级数的运算是或卷积,那么卷积就是:
那么最后子集卷积就是恰取 \(z^{|S|}\) 的答案。
值得一提的是把 \(z\) 放前面一维而不是当多项式更好写也更快。
exp/ln/inv
关于集合幂级数的三种函数:
EXP:
Ln:
Inv:
除了 Inv 的组合意义都挺显然的,然后 Inv 可以代数推导。\(k\) 是 \(\text{lowbit}\) 或者任意一位。
这三个形式事实上都是半在线卷积。
小技巧
提取分式系数:BM。

浙公网安备 33010602011771号