zoukankan      html  css  js  c++  java
  • 从零开始的生成函数学习笔记

    膜拜生成函数之神 ( t Kcolor{red}{arry5307})( t Ccolor{red}{ommand\_block})( t{x}color{red} ext{义}x)

    这个博客基本是贺 ( t Ccolor{red}{ommand\_block}) 的。

    1 幂级数

    幂级数长这样:

    [F(x)=sum_{i=0}^infty F[i]x^i ]

    你可以认为这是一个无穷项的多项式,其中 (i) 次项的多项式就是 (F[i])

    然后同时 (F[i]) 又可以表示成一个数列。

    比如 ({1,1,4,5,1,4,0,0,0,cdots}) 就可以表示成 (4x^5+x^4+5x^3+4x^2+x+1),但是这个东西太臭了,我们换一个。

    比如 ({1,1,1,1,1,cdots}) 就可以表示成 (F(x)=sumlimits_{i=0}^infty x^i)

    然后我们假装这是收敛的(事实上这个幂级数是我们自己搞出来的东西,我们完全可以默认这是收敛的),因此 (F(x)-xF(x)=1),因此 (F(x)) 也可以写成 (F(x)=frac{1}{1-x}) 的形式。由于后面这个简洁的式子显然比前面的更好用,所以我们称后面的那个东西为生成函数的封闭形式

    我们约定 (xrightarrow{ extbf{G}}) 为数列到幂级数的一种简单映射:直接取每个数当作系数。

    然后可以得到一些结论。

    [{1,1,1,1,cdots}xrightarrow{ extbf{G}}sumlimits_{i=0}^infty x^i=frac{1}{1-x} ]

    [{1,a,a^2,a^3,cdots}xrightarrow{ extbf{G}}sumlimits_{i=0}^infty a^ix^i=frac{1}{1-ax} ]

    X 前置组合数学知识

    X.1 组合对象

    我们称一些满足某些性质的元素的集合为组合对象,用 (A) 表示。

    比如 (A) 可以表示有标号荒漠,或者 dead_X 的妹子(没错,空集也是合法的),或者一个字符集为 ( t{0,1}) 的字符串。

    然后 (A) 中的每个元素 (a) 都会有一个大小函数 (size(a))

    比如 (size(a)) 在有标号荒漠的集合中可以表示点的数量,在 dead_X 的妹子的集合中表示年龄,字符串中可以表示串长。

    然后题目一般会问我们“(n) 个点的有标号荒漠数量是多少”,也就是问 (size(a))(n)(ain A) 的数量。我们同样设定一个符号 (A[n]) 来表示这个东西。

    于是我们就把一个集合用数列的方式表达了。

    X.2 笛卡尔积

    (A) 可以做乘法,没想到吧(注意这里的 (A) 是组合对象而不是集合)

    (A_1 imes A_2 imes A_3 imescdots A_n) 还是一个组合对象,它的定义为 (n) 元组 ((a_1,a_2,a_3,cdots,a_n) (a_iin A_i,i=1,2,cdots,n)) 的集合。

    易知 (|A imes B|=|A| imes |B|)

    不难发现,在这个过程中,我们定义了一个新的组合对象。

    2 ( ext{OGF})

    2.1 介绍

    ( ext{OGF}) 的全名是 ( ext{ordinary generating function}),也就是普通生成函数。

    事实上 (xrightarrow{ extbf{G}}) 就是 (xrightarrow{ extbf{OGF}})。我们只需要暴力给每个数乘上 (x^i) 加以区分即可。

    再回顾一下,( ext{OGF}) 就是表示一个数列幂级数,即 ({f_0,f_1,f_2,cdots}xrightarrow{ extbf{OGF}}F(x)=sumlimits_{i=0}^{infty}f_ix^i)。然后又由于一个组合对象也可以用数列的方式组合,因此我们可以用 ( ext{OGF}) 来表示组合对象

    我们已经用之前的 (xrightarrow{ extbf{G}}) 表示了一些 ( ext{OGF}),接着我们再给几个:

    [{inom{n}{0},inom{n}{1},inom{n}{2},cdots,inom{n}{n}}xrightarrow{ extbf{OGF}}(x+1)^n ]

    [{0,frac{1}{1},frac{1}{2},frac{1}{3},frac{1}{4},cdots}xrightarrow{ extbf{OGF}}-ln(1-x) ]

    [{1,frac{1}{1!},frac{1}{2!},frac{1}{3!},frac{1}{4!},cdots}xrightarrow{ extbf{OGF}}e^x ]

    这些都可以自行手推,莫得难度。

    2.2 组合意义

    显然 ( ext{OGF}) 的性质对人类友好一些……

    我们来分析一下 ( ext{OGF}) 在处理一些组合意义时怎么办。

    2.2.1 不交并

    两个不相交集合的并。

    (C(x)=A(x)+B(x))

    加法原理,没啥好说的。

    2.2.2 笛卡尔积

    注意,这里的笛卡尔积一般用于处理无标号对象的组合对象。

    假设我们要求组合对象 (C=A imes B)

    我们再定义 (size(a,b)=size(a)+size(b))

    然后我们就能发现这其实就是一个简单的卷积形式,也就是 (C[i]=sumlimits_{j=0}^iA[j]B[i-j])

    2.3 简单应用(迫真)

    2.3.1 Super Poker II

    好吧这个是真的很简单的应用。

    有四个集合 (A,B,C,D),一开始每个集合里有所有合数 (a_i,b_i,c_i,d_i),然后我们从这些集合去掉 (n) 个数,最后问你在每个集合选出一个数,和为 (l,l+1,cdots,r) 各有几种方案。

    (nleq 10^4,mleq 5 imes 10^4)

    不难发现 (size(a)=sum a),即一个多元组的大小为所有元素之和,于是就满足了上面笛卡尔积的前提。

    不难发现每个 (A[n]) 都在 (n) 是合数且没有被去掉的情况下是 (1),其余情况都是 (0)

    那么就可以 ( ext{FFT}) 卷起来了。

    2.3.2 数学题

    求长度为 (n) 且前 (i) 个字符是数字,后 (n-i) 个字符是小写字母的字符串数量。

    然后你发现这玩意还是可以笛卡尔积。

    不难发现前面这玩意的生成函数是 (frac{1}{1-10x}),后面这玩意的生成函数是 (frac{1}{1-26x}),直接乘起来得到 (frac{1}{(1-10x)(1-26x)}),然后暴力求逆即可。

    2.3.3 数学题II

    长度为 (i) 的骨牌有 (A[i]) 种,每种 (inf) 个,求有多少种方法凑出不重叠,长度为 (1,2,3,cdots,n) 的长条。

    这个题看起来十分不可做。

    我们考虑大力枚举使用 (k) 块骨牌组成 (n) 的方法数,发现就是将 (A) 变成 (A)(k) 次方。

    那么设 (B=A(x)^i)(B) 的每一项就对应着答案。

    而总方案就可以写成用 (1,2,3,cdots,infty) 块骨牌的方法数和。

    于是答案的幂级数就是 (sumlimits_{i=0}^infty A(x)^i)

    根据前面的式子,有 (sumlimits_{i=0}^infty A(x)^i=frac{1}{1-A(x)}),然后就可以欢乐多项式求逆了。

    2.3.3+ 整数的lqp拆分

    不难发现斐波那契数列的生成函数可以写成 (F(x)=frac{1}{1-x-x^2}),那么答案就是 (large frac{1}{1-frac{1}{1-x-x^2}}),直接计算即可。

    你看,就用这个小技巧,我们氵了个黑题

    2.3.4 The Child and Binary Tree

    我们发现当数据出现一些难以处理的限制时,往往能够把限制也搞成一个生成函数。

    我们设 (F[i]) 为权值为 (i) 的神犇二叉树个数。

    我们设 (G[i]) 为是否可以选择点权 (i),可以为 (1),不可以为 (0)

    然后我们考虑怎么 dp 求出 (F[i])

    我们开始思索 (F[i]) 如何拆成 (F[j])

    稍微思考了一下,发现由于题目要求的是有根,无标号,区分左右儿子的二叉树,我们可以拆成左子树和右子树。

    然后就十分简单了:(F[i]=sumlimits_{j=0}^i(G[i-j]sumlimits_{k=0}^jF[k]F[j-k]))

    即先选自身权值,再将剩下的权值分给孩子。

    不难发现这个很能卷积,于是变成生成函数。

    [F(x)=G(x)F(x)^2 ]

    诶,这个好像不对?

    哦,(F[0]=1),但是 (G[0]=0) 把它去掉了,所以我们给右边加 (1)

    [F(x)=G(x)F(x)^2+1 ]

    解一元二次方程。

    [x=frac{-bpmsqrt{b^2-4ac}}{2a} ]

    [F(x)=frac{1pmsqrt{1-4G(x)}}{2G(x)} ]

    判断 (pm) 应该取负,然后就可以多项式开根,求逆然后乘起来了。

    ( t Ccolor{red}{ommand\_block}) 给出了一种减小常数的方法:

    [frac{1-sqrt{1-4G(x)}}{2G(x)} ]

    [=frac{(1-sqrt{1-4G(x)})(1+sqrt{1-4G(x})}{2G(x)(1+sqrt{1-4G(x}))} ]

    [=frac{4G(x)}{2G(x)(1+sqrt{1-4G(x)})} ]

    [=frac{2}{1+sqrt{1-4G(x)}} ]

    常数减小了!

    2.3.5 [集训队作业2013]城市规划

    我们发现连通图依旧是一个限制条件,我们尝试去掉限制,发现 (n) 个点的简单图很好算。

    我们设 (F[i])(n) 个点的连通图数量。

    我们设 (G[i])(n) 个点的图数量。

    不难发现如果我们考虑将 (1) 号点所在的连通块和原图分开,则有

    [G[i]=sumlimits_{j=1}^iF[j]dbinom{i-1}{j-1}G[i-j] ]

    [G[i]=sumlimits_{j=1}^iF[j]frac{(i-1)!}{(j-1)!(i-j)!}G[i-j] ]

    [G[i]=(i-1)!sumlimits_{j=1}^i(F[j]frac{1}{(j-1)!})(G[i-j]frac{1}{(i-j)!}) ]

    然后你发现 (G[i]=2^inom{i}{2})

    [frac{2^inom{i}{2}}{(i-1)!}=sumlimits_{j=1}^i(F[j]frac{1}{(j-1)!})(2^inom{i-j}{2}frac{1}{(i-j)!}) ]

    于是把这三个神奇的式子分别记为 (A[i],B[j],C[i-j]),就有 (C(x)=A(x) imes B(x)) 了。

    由于我们知道 (B)(C),于是开始一通多项式高级操作,这题就做完了。

    3 ( ext{EGF})

    3.1 介绍

    ( ext{EGF}) 的全名是 ( ext{ordinary generating function}),也就是 exp 生成函数。

    [{f_0,f_1,f_2,cdots}xrightarrow{ extbf{EGF}}F(x)=sumlimits_{i=0}^{infty}f_ifrac{x^i}{i!} ]

    注意,这里 (f_0 eq F[0]) 了!

    列举一些常见 ( ext{EGF}) 的封闭形式:

    [{1,1,1,1,cdots}xrightarrow{ extbf{EGF}}e^x ]

    [{1,-1,1,-1,cdots}xrightarrow{ extbf{EGF}}e^{-x} ]

    [{1,a,a^2,a^3,cdots}xrightarrow{ extbf{EGF}}e^{ax} ]

    [{1,0,1,0,cdots}xrightarrow{ extbf{EGF}}frac{e^x+e^{-x}}{2} ]

    3.2 组合意义

    3.2.1 不交并

    (C(x)=A(x)+B(x))

    加法原理,没啥好说的。

    3.2.2 笛卡尔积

    注意,这里的笛卡尔积一般用于处理有标号对象的组合对象。

    假设我们要求组合对象 (C=A imes B)

    我们再定义 (size(a,b)=size(a)+size(b))

    然后此时我们定义两个组合对象相加后可以改变相对顺序,但内部顺序保持原样。

    然后我们先观察序列:(C_i=sumlimits_{j=0}^nA_jB_{i-j}inom{i}{j})

    那么就有

    [C_{i}=sumlimits_{j=0}^iA_{j}B_{i-j}inom{i}{j} ]

    [C_{i}=sumlimits_{j=0}^iA_{j}B_{i-j}frac{i!}{j!(i-j)!} ]

    [frac{C_i}{i!}=sumlimits_{j=0}^ifrac{A_j}{j!}frac{B_{i-j}}{(i-j)!} ]

    [C[i]=sumlimits_{j=0}^iA[j]B[i-j] ]

    你可以理解为,( ext{OGF}) 是把两样东西原封不动拼接起来,而 ( ext{EGF}) 则是混合起来了。

    具体可以看第一个例子。

    2.3 简单应用(迫真)

    2.3.1 数学题III

    你有 (n) 个格子,你打算把每个格子涂成 (color{#1f1e33} t{1f1e33})(color{#114514} t{114514})(color{#191981} t{191981}) 中的一种颜色。

    由于野兽先辈和原野二人幸终,所以你要求 (color{#114514} t{114514})(color{#191981} t{191981}) 必须涂偶数次。

    你想知道有多少种涂色的方法。

    我们套路地设 (F(x),G(x),H(x)) 为用三种颜色涂 (i) 个格子的方法数的 ( ext{EGF}),那么

    [F_i={1,1,1,1,cdots} ]

    [G_i=H_i={1,0,1,0,cdots} ]

    然后你惊奇地发现,用两种颜色涂格子的方法的方法数的 ( ext{EGF}) 就是将两种用一种颜色涂格子的方法数的 ( ext{EGF}) 乘起来。

    • 证明:(i) 个数选 (j) 个用第一种,剩下的用第二种。

    于是这道题就做完了。

    2.3.2 无聊的水题I

    首先,你要知道有 prufer 序列这个东西。

    但是你并不需要了解它,你只需要知道两个结论:

    1. (n) 个节点的有标号无根树和长度为 (n-2),元素为节点编号的序列一一对应,也就是双射
    2. 一个长度为 (n-2),元素为节点编号的序列所代表的树中,每个节点的度数为它在序列中出现次数 (+1)

    不难想道把阴间的恰好转化成不超过然后相减,所以要求的东西如下:

    一个长度为 (n-2),值域为 ([1,n]) 的整数,每个数出现次数小于 (k) 的序列的个数。

    那么我们就可以整出 ( ext{EGF}) 了,( ext{EGF}) 即为 ({frac{1}{0!},frac{1}{1!},frac{1}{2!},cdots,frac{1}{(k-1)!},0,0,0,cdots})

    于是设上面那玩意是 (F(x)),我们只需要求 (F(x)^{n}),直接上多项式快速幂即可。

    复杂度 (O(nlog n))

  • 相关阅读:
    使用 Dockerfile 定制镜像
    UVA 10298 Power Strings 字符串的幂(KMP,最小循环节)
    UVA 11090 Going in Cycle!! 环平均权值(bellman-ford,spfa,二分)
    LeetCode Best Time to Buy and Sell Stock 买卖股票的最佳时机 (DP)
    LeetCode Number of Islands 岛的数量(DFS,BFS)
    LeetCode Triangle 三角形(最短路)
    LeetCode Swap Nodes in Pairs 交换结点对(单链表)
    LeetCode Find Minimum in Rotated Sorted Array 旋转序列找最小值(二分查找)
    HDU 5312 Sequence (规律题)
    LeetCode Letter Combinations of a Phone Number 电话号码组合
  • 原文地址:https://www.cnblogs.com/dead-X/p/generating-function.html
Copyright © 2011-2022 走看看