当前位置:网站首页>Zscoder‘s 生成函数教程(三)
Zscoder‘s 生成函数教程(三)
2022-08-06 23:43:00 【爱寂寞的时光】
Zscoder‘s 生成函数教程(三)
本文翻译自 zscoder 的 CF Blog 文章 [Tutorial] Generating Functions in Competitive Programming (Part 2) 。
本文是原文的第二部分,生成函数在 CP 中实战。
如有侵权,联系作者将尽快删除;如有翻译不足之处,敬请指出。
注意:除非有特殊情况,我们都是在模 998244353 998244353 998244353 的意义下计算。 [ n ] [n] [n] 指的是集合 { 1 , 2 , 3 , … , n } \{1,2,3,\ldots,n\} { 1,2,3,…,n} 。
显然的计数问题
首先,我们需要做一个基础计数。对于一个顶点集 S S S ,令 t ( S ) t(S) t(S) 为包含 S S S 的最小的子树。
固定 k k k 的情况下如何计算 f ( S ) f(S) f(S) 呢?如果我们单独看一个顶点 v v v ,计算有多少个大小为 k k k 的 S S S 满足 t ( S ) t(S) t(S) 包含 v v v 是比较困难的。然而,我们单独的看一个边 e e e ,计算有多少个大小为 k k k 的 S S S 满足 t ( S ) t(S) t(S) 包含 e e e 是相对简单的。我们只需要删去 e e e 然后在两个连通分量中选择 k k k 个节点,这些节点的 t ( S ) t(S) t(S) 是一定包含 e e e 的。换句话说,如果我们删除 e e e 那么整棵树就变成了两个大小分别为 a a a 和 n − a n-a n−a 的连通分量,我们计算 ∑ e ∈ E ( n k ) − ( a k ) − ( n − a k ) \sum_{e \in E} \binom{n}{k} - \binom{a}{k} - \binom{n-a}{k} ∑e∈E(kn)−(ka)−(kn−a) ,这些是 t ( S ) , ∣ S ∣ = k t(S),|S| = k t(S),∣S∣=k 中所有边的数量,又因为在树中点的数量等于边的数量加一,因此 a n s k = ( n k ) + ∑ e ∈ E ( n k ) − ( a k ) − ( n − a k ) {ans}_k = \binom{n}{k} + \sum_{e \in E} \binom{n}{k} - \binom{a}{k} - \binom{n-a}{k} ansk=(kn)+∑e∈E(kn)−(ka)−(kn−a) 。
通过dfs,我们能计算出所有的 a a a ,记为 a 1 , a 2 , … , a n − 1 a_1,a_2,\ldots,a_{n-1} a1,a2,…,an−1 。如果我们能快速计算出对于所有 1 ≤ k ≤ n 1 \le k \le n 1≤k≤n 和式 ∑ i = 1 n − 1 ( a i k ) \sum_{i=1}^{n-1} \binom{a_i}{k} ∑i=1n−1(kai) 的值,那我们的问题就解决了。
我们使用一个小技巧,令 c i c_i ci 为 i i i 出现在 a 1 , a 2 , … , a n − 1 a_1,a_2,\ldots,a_{n-1} a1,a2,…,an−1 中的次数,那么我们所求为 ∑ i = 0 n c i ( i k ) \sum_{i=0}^{n} c_i \binom{i}{k} ∑i=0nci(ki) 。
接下来使用一个打开组合数的一个套路:
∑ i = 0 n c i ( i k ) = ∑ i = 0 n c i i ! k ! ( i − k ) ! = 1 k ! ∑ i = 0 n i ! c i 1 ( i − k ) ! \sum_{i=0}^{n} c_i \binom{i}{k} = \sum_{i=0}^{n} c_i \frac{i!}{k!(i-k)!} = \frac{1}{k!} \sum_{i=0}^{n} i!c_i \frac{1}{(i-k)!} i=0∑nci(ki)=i=0∑ncik!(i−k)!i!=k!1i=0∑ni!ci(i−k)!1
显然,我们只需要知道如何对于所有的 k k k 快速计算 ∑ i = 0 n i ! c i 1 ( i − k ) ! \sum_{i=0}^{n} i!c_i \frac{1}{(i-k)!} ∑i=0ni!ci(i−k)!1 。如果你学过生成函数,这非常像两个生成函数的卷积。我们引入 F ( x ) = ∑ i ≥ 0 f ( i ) x i F(x) = \sum_{i \ge 0} f(i)x^i F(x)=∑i≥0f(i)xi 和 G ( x ) = ∑ i ≥ 0 g ( i ) x i G(x) = \sum_{i \ge 0} g(i)x^i G(x)=∑i≥0g(i)xi 。
那么 C ( x ) = ∑ k ≥ 0 x k ∑ i = 0 n i ! c i 1 ( i − k ) ! = ∑ k ≥ 0 x k ∑ i = 0 n f ( i ) g ( k − i ) = F ( x ) G ( x ) C(x) = \sum_{k \ge 0}x^k \sum_{i=0}^{n} i!c_i \frac{1}{(i-k)!} = \sum_{k \ge 0}x^k \sum_{i=0}^{n} f(i)g(k-i) = F(x)G(x) C(x)=∑k≥0xk∑i=0ni!ci(i−k)!1=∑k≥0xk∑i=0nf(i)g(k−i)=F(x)G(x) 。
显然,我们令 f ( i ) = i ! c i f(i) = i!c_i f(i)=i!ci 而 g ( i ) = 1 ( − i ) ! g(i) = \frac{1}{(-i)!} g(i)=(−i)!1 ,然而当 i > 0 i \gt 0 i>0计算 ( − i ) ! (-i)! (−i)! 是没有意义的。问题不大,我们只需要平移我们的生成函数,让 x − i x^{-i} x−i 部分移动至 x n − i x^{n-i} xn−i 。此时,当我们想获取原生成函数的 x k x^k xk 次项系数的时候,我们需要获取新生成函数的 x k + n x^{k+n} xk+n 次项。
遇到卷积问题通常使用生成函数和多项式求解,然而生成函数的强大远不及此。
问题。CF438 E
这在六年前是一道 3100 分的题目,但是现在你已经在2020年知道了多项式算法(这个年代多项式算法已经非常普及),那就非常简单了。
首先,显然的构造 f s f_s fs 是我们对于 s s s 的答案,令 F ( x ) F(x) F(x) 为 f s f_s fs 的 OGF 。
显然, f 0 = 1 f_0 = 1 f0=1 。对于 s > 0 s \gt 0 s>0 我们模仿 Catalan 数找到一个递归式:
f s = ∑ c ∈ C ∑ i ≥ 0 f i f s − c − i f_s = \sum_{c \in C} \sum_{i \ge 0}f_if_{s-c-i} fs=c∈C∑i≥0∑fifs−c−i
用生成函数的语言表达,就是:
∑ s ≥ 1 f s x s = ∑ s ≥ 1 ∑ c ∈ C x c ∑ i ≥ 0 f i x i f s − c − i x s − c − i \sum_{s \ge 1} f_s x^s = \sum_{s \ge 1}\sum_{c \in C} x^c \sum_{i \ge 0}f_ix^if_{s-c-i}x^{s-c-i} s≥1∑fsxs=s≥1∑c∈C∑xci≥0∑fixifs−c−ixs−c−i
令 F ( x ) = ∑ s ≥ 0 f s x s F(x) = \sum_{s \ge 0} f_s x^s F(x)=∑s≥0fsxs 和 C ( x ) = ∑ c ∈ C x c C(x) = \sum_{c \in C} x^c C(x)=∑c∈Cxc 那么上面的式子不就是:
F ( x ) − 1 = F ( x ) 2 C ( x ) F(x) - 1 = F(x)^2 C(x) F(x)−1=F(x)2C(x)
解这个二次方程得到 F ( x ) = 1 ± 1 − 4 C ( x ) 2 C ( x ) F(x) = \frac{1 \pm \sqrt{1-4C(x)}}{2C(x)} F(x)=2C(x)1±1−4C(x) ,当 x → 0 x \to 0 x→0 的时候, F ( x ) → 1 F(x) \to 1 F(x)→1 使用洛必达法则确定符号为负号,因此 F ( x ) = 1 − 1 − 4 C ( x ) 2 C ( x ) F(x) = \frac{1 - \sqrt{1-4C(x)}}{2C(x)} F(x)=2C(x)1−1−4C(x) 。
到这里我们基本就做完了,但是还有个实现上的细节。我们知道 C ( x ) C(x) C(x) 的常数项为 0 0 0 这代表 C ( x ) C(x) C(x) 没有逆元。我们对上面的式子进行分子有理化:
F ( x ) = 1 − 1 − 4 C ( x ) 2 C ( x ) = ( 1 − 1 − 4 C ( x ) ) ( 1 + 1 − 4 C ( x ) ) 2 C ( x ) ( 1 + 1 − 4 C ( x ) ) = 4 C ( x ) 2 C ( x ) ( 1 + 1 − 4 C ( x ) ) = 2 1 + 1 − 4 C ( x ) F(x) = \frac{1 - \sqrt{1-4C(x)}}{2C(x)} = \frac{(1 - \sqrt{1-4C(x)})(1 + \sqrt{1-4C(x)})}{2C(x)(1 + \sqrt{1-4C(x)})} = \frac{4C(x)}{2C(x)(1 + \sqrt{1-4C(x)})} = \frac{2}{1 + \sqrt{1-4C(x)}} F(x)=2C(x)1−1−4C(x)=2C(x)(1+1−4C(x))(1−1−4C(x))(1+1−4C(x))=2C(x)(1+1−4C(x))4C(x)=1+1−4C(x)2
我们要计算前 m m m 项,因此使用多项式算法的时间复杂度为 O ( m log m ) O(m \log m) O(mlogm) 。
实话说,也不能说这个题简单因为主要的难点在于计算多项式的平方根和多项式的倒数,这在6年前很少有人知道,但是在现在你可以在网上找到大量多项式的板子,我们只需要思考问题本身。
这道题有一个 O ( n 2 k ) O(\frac{n^2}{k}) O(kn2) 的 DP 算法(试一试),但是无法通过这道题目。我们需要使用生成函数。令 f ( n ) f(n) f(n) 是我们的答案( k k k 是固定的)。
关键的思想就在于“恰好”条件是困难的,而“至少”条件是简单的。令 f ( S ) f(S) f(S) 指的是恰好只在点集 S S S 处下降的排列数量。而 g ( S ) g(S) g(S) 是在点集 S S S 的任意子集处下降的排列数量。显然 g ( S ) = ∑ T ∈ S f ( T ) g(S) = \sum_{T \in S}f(T) g(S)=∑T∈Sf(T) 。使用容斥原理,我们能得到 f ( S ) = ∑ T ⊆ S ( − 1 ) ∣ S ∣ − ∣ T ∣ g ( T ) f(S) = \displaystyle\sum_{T \subseteq S}(-1)^{|S| - |T|}g(T) f(S)=T⊆S∑(−1)∣S∣−∣T∣g(T) 。
g ( S ) g(S) g(S) 实际上更好计数。假设 S = { s 1 , s 2 , … , s m } S=\{s_1,s_2,\ldots,s_m\} S={ s1,s2,…,sm} 在这里 s i < s i + 1 s_i \lt s_{i+1} si<si+1 。一个更好的理解就是将整个排列分成 m m m 块上升的块。这等于将 n n n 个元素分成 m m m 类,也就是 1 s 1 ! ( s 2 − s 1 ) ! ( s 3 − s 2 ) ! . . . ( n − s m ) ! \frac{1}{s_{1}!(s_{2}-s_{1})!(s_{3}-s_{2})!...(n-s_{m})!} s1!(s2−s1)!(s3−s2)!...(n−sm)!1 。因此 g ( S ) = n ! s 1 ! ( s 2 − s 1 ) ! ( s 3 − s 2 ) ! . . . ( n − s m ) ! g(S) = \frac{n!}{s_{1}!(s_{2}-s_{1})!(s_{3}-s_{2})!...(n-s_{m})!} g(S)=s1!(s2−s1)!(s3−s2)!...(n−sm)!n! 。
为了简单,我们令 D = k , 2 k , 3 k , … ∩ [ n − 1 ] D = k,2k,3k,\ldots \cap [n-1] D=k,2k,3k,…∩[n−1] 。我们需要计算 f ( D ) f(D) f(D) 。
任何的 D D D 的子集 T = { s 1 , s 2 , … , s m − 1 } T=\{s_1,s_2,\ldots,s_{m-1}\} T={ s1,s2,…,sm−1} (以升序排列)能够描述为 b 1 , b 2 , … , b m b_1,b_2,\ldots,b_m b1,b2,…,bm 其中 b i = s i − s i − 1 b_i = s_i - s_{i-1} bi=si−si−1 。特别的 s 0 = 0 , s m = n s_0=0,s_m=n s0=0,sm=n 指的是每一块的大小。将 g ( T ) g(T) g(T) 化简为 G ( T ) = n ! b 1 ! b 2 ! … b m ! G(T) = \frac{n!}{b_1!b_2!\ldots b_m!} G(T)=b1!b2!…bm!n! 。
因此:
f ( D ) = ∑ T ⊆ D ( − 1 ) ∣ D ∣ − ∣ T ∣ g ( T ) = ∑ ∑ b i = n , b i good ( − 1 ) ∣ D ∣ − ( m − 1 ) n ! b 1 ! b 2 ! . . . b m ! f(D) = \displaystyle\sum_{T \subseteq D}(-1)^{|D| - |T|}g(T) = \displaystyle\sum_{\sum b_{i} = n, b_{i} \text{ good}}(-1)^{|D|-(m-1)}\frac{n!}{b_{1}!b_{2}!...b_{m}!} f(D)=T⊆D∑(−1)∣D∣−∣T∣g(T)=∑bi=n,bi good∑(−1)∣D∣−(m−1)b1!b2!...bm!n!
为了表示简单,我们将长度 n n n 表示为 k q + r kq+r kq+r 的这种形式,注意因为当 n n n 是 k k k 的倍数的时候位置 n n n 不应该考虑,因此 1 ≤ r ≤ k 1 \le r \le k 1≤r≤k 。我们使用 EGF。
F ( x ) = ∑ q ≥ 0 f ( k q + r ) ( k q + r ) ! x k q + r F(x) = \sum_{q \ge 0} \frac{f(kq+r)}{(kq+r)!}x^{kq+r} F(x)=q≥0∑(kq+r)!f(kq+r)xkq+r
= ∑ q ≥ 0 ∑ m ≥ 1 ∑ ∑ b i = k q + r , b i good ( − 1 ) q − m + 1 ( k q + r ) ! b 1 ! b 2 ! . . . b m ! ⋅ x k q + r ( k q + r ) ! = \displaystyle\sum_{q \ge 0}\displaystyle\sum_{m \ge 1}\displaystyle\sum_{\sum b_{i} = kq+r, b_{i} \text{ good}}(-1)^{q-m+1}\frac{(kq+r)!}{b_{1}!b_{2}!...b_{m}!} \cdot \frac{x^{kq+r}}{(kq+r)!} =q≥0∑m≥1∑∑bi=kq+r,bi good∑(−1)q−m+1b1!b2!...bm!(kq+r)!⋅(kq+r)!xkq+r
= ∑ m ≥ 1 ∑ q ≥ 0 ∑ ∑ b i = k q + r , b i good ( − 1 ) q − m + 1 x b 1 ⋅ x b 2 ⋅ . . . ⋅ x b m b 1 ! b 2 ! . . . b m ! = \displaystyle\sum_{m \ge 1}\displaystyle\sum_{q \ge 0}\displaystyle\sum_{\sum b_{i} = kq+r, b_{i} \text{ good}}(-1)^{q-m+1}\frac{x^{b_{1}} \cdot x^{b_{2}} \cdot ... \cdot x^{b_{m}}}{b_{1}!b_{2}!...b_{m}!} =m≥1∑q≥0∑∑bi=kq+r,bi good∑(−1)q−m+1b1!b2!...bm!xb1⋅xb2⋅...⋅xbm
= ∑ m ≥ 1 ( ∑ i ≥ 1 ( − 1 ) i − 1 ⋅ x k i ( k i ) ! ) m − 1 ⋅ ( ∑ i ≥ 0 ( − 1 ) i ⋅ x k i + r ( k i + r ) ! ) = \displaystyle\sum_{m \ge 1}\displaystyle\left(\displaystyle\sum_{i \ge 1}\frac{(-1)^{i-1} \cdot x^{ki}}{(ki)!}\right)^{m-1} \cdot \left(\displaystyle\sum_{i \ge 0}\frac{(-1)^{i} \cdot x^{ki+r}}{(ki+r)!}\right) =m≥1∑(i≥1∑(ki)!(−1)i−1⋅xki)m−1⋅(i≥0∑(ki+r)!(−1)i⋅xki+r)
花一点时间理解一些最后一个卷积。我们卷 m − 1 m-1 m−1 次整区间,最后一次卷积包含 r r r 。
继续化简我们得到:
= ( ∑ i ≥ 0 ( − 1 ) i ⋅ x k i + r ( k i + r ) ! ) ⋅ ∑ m ≥ 1 ( ∑ i ≥ 1 ( − 1 ) i − 1 ⋅ x k i ( k i ) ! ) m − 1 = \left(\displaystyle\sum_{i \ge 0}\frac{(-1)^{i} \cdot x^{ki+r}}{(ki+r)!}\right) \cdot \displaystyle\sum_{m \ge 1}\displaystyle\left(\displaystyle\sum_{i \ge 1}\frac{(-1)^{i-1} \cdot x^{ki}}{(ki)!}\right)^{m-1} =(i≥0∑(ki+r)!(−1)i⋅xki+r)⋅m≥1∑(i≥1∑(ki)!(−1)i−1⋅xki)m−1
= ( ∑ i ≥ 0 ( − 1 ) i ⋅ x k i + r ( k i + r ) ! ) ⋅ 1 1 − ( ∑ i ≥ 1 ( − 1 ) i − 1 ⋅ x k i ( k i ) ! ) = \left(\displaystyle\sum_{i \ge 0}\frac{(-1)^{i} \cdot x^{ki+r}}{(ki+r)!}\right) \cdot \frac{1}{1 - \left(\displaystyle\sum_{i \ge 1}\dfrac{(-1)^{i-1} \cdot x^{ki}}{(ki)!}\right)} =(i≥0∑(ki+r)!(−1)i⋅xki+r)⋅1−(i≥1∑(ki)!(−1)i−1⋅xki)1
= ∑ i ≥ 0 ( − 1 ) i ⋅ x k i + r ( k i + r ) ! ∑ i ≥ 0 ( − 1 ) i ⋅ x k i ( k i ) ! = \frac{\displaystyle\sum_{i \ge 0}\frac{(-1)^{i} \cdot x^{ki+r}}{(ki+r)!}}{\displaystyle\sum_{i \ge 0}\dfrac{(-1)^{i} \cdot x^{ki}}{(ki)!}} =i≥0∑(ki)!(−1)i⋅xkii≥0∑(ki+r)!(−1)i⋅xki+r
我们在 O(n \log n) 的情况下能计算出第 n n n 项,这道题就做完了。通过 EGF ,你能够消去分子中的阶乘分配分母的阶乘构造卷积。
边栏推荐
- 今日睡眠质量记录70分
- Promise的点点滴滴
- Machine Learning | MATLAB implements support vector machine classification ClassificationSVM parameter setting
- [Combat of High Concurrency Projects] Principle Analysis of Engineering Modularity and Static Architecture of Event Venues
- 深度学习:可视化方法
- Record the days we went through together
- 使用plugin DSL引用自定义gradle plugin
- Sql server无法启动
- 【超好懂的比赛题解】2022 Jiangsu Collegiate Programming Contest 比赛题解
- Those MP3s who are reluctant to delete--modify the ID3tag of mp3 in batches
猜你喜欢

语言模型大串烧之变形金刚

Easily complete interface testing and interface documentation

bugku 简单取证1

stm32学习(入门2)

What is the matter with several IP addresses of this machine?to analyze

leetcode 20. 有效的括号

今日睡眠质量记录70分

Zabbix5.0 deployment + monitoring service, detailed explanation of pictures and texts, effective personal test!!

复制天猫的宝贝上传到淘宝,SKU自定义属性值没有复制过来是什么原因?

轻松完成接口测试及接口文档
随机推荐
时序预测 | MATLAB实现XGBoost极限梯度提升树时间序列预测
2.基于ITIL的IT服务管理基础篇 --- IT服务管理的背景
What is the matter with several IP addresses of this machine?to analyze
The fifty-fifth use of three.js to pass uniform to shader notes
Yolov5
面试遇见简单算法总结
抖音众多接口展示
bugku 简单取证1
PAT乙级-B1023 组个最小数(20)
ansible 一题多解
PAT Grade B-B1023 Minimum Number of Groups (20)
micronet ICCV2021
Promise的点点滴滴
数据库原理(三)——关系代数
那些舍不得删除的 MP3--批量修改mp3的ID3tag
深入了解集合的使用方法
头像上传功能
Public Relations and Interpersonal Skills
惯性测量单元预积分原理与实现
leetcode 21. 合并两个有序链表(可进阶)