zoukankan      html  css  js  c++  java
  • 生成函数

    生成函数

    普通生成函数(OGF)

    定义

    对于一类对象构成的集合 (A) ,若满足

    • 对于每个元素 (ain A) ,定义非负整数 (|a|) 为元素 (a) 的“大小”或“权值”
    • 对于给定的 (n) ,大小为 (n) 的元素的个数是有限的(但 (A) 可以是无限集),其对应的元素个数记为 (A_n)

    我们定义 (A(x)=sumlimits_{nge 0}A_nx^n) 为 集合 (A) 的普通生成函数。

    注意这里的 (A(x)) 认为是一个形式幂级数,在 (mod x^n) 以及系数 (mod P) 的意义下运算

    基本运算

    设有两个集合 (A,B)

    定义它们的不交并为 (C) ,则 (C(x)=A(x)+B(x))

    通俗点其实就是把它们的元素原来是什么样还是什么样塞到 (C) 里面

    定义两个集合的笛卡尔积为 (D) ,则 (D=A*B),这里指卷积。

    意思是对于 (ain A,bin B),我们有 (d=a+b,|d|=|a|+|b|) (这里前面可以简单的理解成定义了元素的并 (b)

    序列OGF

    对于一类对象构成的集合 (A),定义 (mathbf {SEQ}(A)) 是由 (A) 的元素排列而成的序列组成的集合,对于其中某一个长度为 (n) 的序列,可以看作是 (n)(A) 进行笛卡尔积的结果。

    例如 (A={0,1}) 即字符 (0,1) 构成的二元集,则 (mathbf {SEQ(A)}) 表示所有的 (01) 字符串。

    例如 (A=mathbb Z^+) 即正整数集,则 (mathbf {SEQ} (A)) 表示正整数序列。

    对于 (mathbf {SEQ}(A)) 中的一个元素 ((a_1,a_2,dots)) ,定义其大小为(|a_1|+|a_2|+dots) ,那么显然有序列 (mathbf{SEQ} (A))(OGF)(mathbf {SEQ} (A)=1+A+A^2+dots=frac{1}{1-A})

    下面给出用 序列OGF 进行数数的例子

    (A={0,1}) 即字符 (0,1) 构成的二元集

    • 我们定义所有元素的大小为 (1) ,则 (A) 的生成函数为 (A(x)=2x)

    (mathbf {SEQ} (A)) 的生成函数为 (1+2x+4x^2+8x^3+dots) ,其系数表示长度为 (i) 的序列的个数

    我们也可以定义元素 (i) 的大小为 (|i|) ,则序列 (A) 的生成函数为 (A(x)=1+x)

    (mathbf {SEQ} (A)) 的生成函数为 (1+(1+x)+(1+x)^2+(1+x)^3+dots) ,其系数表示有 (i) 个元素 (1)的序列 的个数

    (A=mathbb Z^+) 即正整数集

    • 定义元素 (i) 的大小为 (|i|) ,则 (A) 的生成函数为 (A(x)=sumlimits_{ige 1}x^i=frac{x}{1-x})

    (mathbf {SEQ}(A)) 的生成函数为 (frac{1}{1-A}=1+x+2x^2+4x^3+8x^4+dots),其系数实际上表示的是正整数的有序拆分数。

    常见数列的 OGF

    [egin{aligned} &<1,0,0,dots>Rightarrow A(x)=1\ &<1,1,1,dots>Rightarrow A(x)=1+x+x^2+dots=frac{1}{1-x}\ &<1,-1,1,dots>Rightarrow A(x)=1-x+x^2-dots=frac{1}{(1+x)}\ &<1,2,3,dots>Rightarrow A(x)=1+2x+3x^2+dots=(1+x+x^2+dots)^2=frac{1}{(1-x)^2}\ end{aligned} ]


    指数生成函数(EGF)

    定义

    对于一类带标号对象构成的集合 (A) ,若满足 (OGF) 的两个要求

    我们定义 (A(x)=sumlimits_{nge 0}frac{A_n}{n!}x^n) 为集合 (A) 的指数生成函数。

    带标号对象是为了合并两个带标号集合。当两个大小分别为 (n,m) 的带标号集合进行合并时,需要重新进行标号,并保留在原集合的相对标号,其方案数为 (inom{n+m}{m})

    基本运算

    (OGF) ,但笛卡尔积合并的是两个带标号集合。

    序列EGF

    对于一类带标号对象构成的集合 (A),定义 (mathbf {SEQ}(A)) 是由 (A) 的元素排成的序列组成的集合且进行保序重标号,其余与 (OGF) 类似。

    集合EGF

    对于一类带标号对象构成的集合 (A),定义 (mathbf{SET}(A)) 是由 (A) 的子集组成的集合且进行保序重标号。但由于 (A) 的子集互相间是无序的,所有有 (mathbf{SET}(A)=1+A+frac{A^2}{2!}+frac{A^3}{3!}+dots=e^A)

    下面给出用 集合EGF 进行数数的例子

    (G) 为所有带标号简单无向图构成的集合

    • 定义每个图的大小为它的点数,则 (G) 的生成函数为 (sumlimits_{nge 0} frac{2^{inom{n}{2}}}{n!}x^i)

    (G^+) 为所有简单无向连通图构成的集合

    • 定义每个图的大小为它的点数,则有 (G=mathbf{SET} (G^+)=e^{G^+})

    所以有 (G^+=ln G)

    (T) 为所有带标号树构成的集合

    • 定义每个图的大小为它的点数,则 (T) 的生成函数为 (sumlimits_{nge 0}frac{n^{n-2}}{n!}x^i)

    (F) 为所以带标号森林构成的集合

    • 定义每个图的大小为它的点数,则有 (F=e^T)

    常见数列的 EGF

    [egin{aligned} <1,1,1,dots>&Rightarrow A(x)=1+x+frac{x^2}{2}+frac{x^3}{6}+dots=e^x\ <0,1,2,dots>&Rightarrow A(x)=x+x^2+frac{x^3}{2}+frac{x^4}{6}+dots=xe^x\ <1,c,c^2dots>&Rightarrow A(x)=x+cx+frac{c^2x^2}{2}+frac{c^3x^3}{6}+dots=e^{cx}\ end{aligned} ]


    常见数列与生成函数

    Fibonacci 数列

    设 Fib 数列 (<1,1,2,3,5,dots>) 的 OGF 为 (F(x))

    [egin{aligned} F(x)=&1+x+2x^2+3x^3+5x^4+dots\ =&1+x(1+2x+3x^2+5x^3+dots)\ =&1+x(1+x+2x^2+3x^3+dotsc+x(1+x+2x^2+dots))\ =&1+xF(x)+x^2F(x)\ end{aligned} ]

    化简后得

    [F(x)=frac{1}{1-x-x^2} ]

    然后可以在 (O(nlog n)) 的复杂度求解 Fib 辣

    这个没什么用,如果有兴趣可以把这个式子展开推一下通项。

    Catalan 数列

    设 Cat 数列 (<1,2,5,14,42,dots>) 的 OGF 为 (C(x))

    我们知道 Cat 可以描述一个 (n) 个点构成的不同形态的二叉树个数,因此存在递推公式 (c_n=sumlimits_{0le i< n}c_ic_{n-i-1})

    因此有

    [egin{aligned} C(x)&=sum_{nge 0}c_nx^n\ &=sum_{nge 0}([n=0]+sum_{0le ile n-1}c_ic_{n-i-1})x^n\ &=1+xsum_{nge 1}sum_{0le ile n-1}c_ic_{n-i-1}x^{n-1}\ &=1+xC(x)^2 end{aligned} ]

    化简得

    [C(x)=frac{1pm sqrt{1-4x}}{2x} ]

    考虑代入 (C(0)=1) 得到正负号(这是通用方法)

    这个其实也没啥用,因为我们有 (O(n)) 求解卡特兰数的方法,可以展开生成函数求得通项

    [C(x)=sum_{nge 0}frac{(2n)!}{[n!(n+1)!]}x^n ]

    Bell 数

    Bell 数 (w_n) 表示将大小为 (n) 的集合分割成若干个非空不相交子集的方案数,定义 (w_0=1)

    考虑枚举第一个元素所在的子集大小进行递推,有

    [w_n=sum_{1le i le n-1}inom{n-1}{i-1}w_{n-i} ]

    设其的 EGF 为 (B(x))

    [egin{aligned} B(x)=&sum_{nge 0}frac{w_n}{n!}x^n\ =&1+sum_{nge 1}(sum_{1le ile n}inom{n-1}{i-1}w_{n-i})frac{1}{n!}x^n\ =&1+sum_{nge 1}(sum_{1le ile n}frac{w_{n-i}}{(n-i)!}frac{x^n}{(i-1)!n})\ =&1+sum_{nge 1}(sum_{0le i <n}frac{w_i}{i!}frac{x^n}{(n-i-1)!n})\ =&1+sum_{ige 0}frac{w_i}{i!}sum_{n>i}frac{x^n}{(n-i-1)!n}\ end{aligned} ]

    考虑到右边分母的 (n) 不友好,那么进行求导

    [egin{aligned} B(x)'&=sum_{ige 0}frac{w_i}{i!}sum_{n>i}frac{x^{n-1}}{(n-i-1)!}\ &=sum_{ige 0}frac{w_i}{i!}sum_{nge 0}frac{x^{n+i}}{n!}\ &=sum_{ige 0}frac{w_i}{i!}x^ie^x\ &=B(x)e^x end{aligned} ]

    下面求解微分方程

    [egin{aligned} &frac{B(x)'}{B(x)}=e^x\ &int frac{B(x)'}{B(x)} mathbb dB(x)=int e^x mathbb dx\ &ln(B(x))=e^x+C\ &B(x)=e^{e^x+C} end{aligned} ]

    代入 (B(0)=1) 可以得到常数 (C=-1)

    因此 (B(x)=e^{e^x-1})

    当然,也可以直接简单粗暴的用组合意义来说明 Bell 数的 EGF,设 (A(x)) 表示 (n) 个数组成一个非空集合的方案数

    那么 (A(x)=x+frac{x^2}{2}+frac{x^3}{3!}+dots=e^x-1)

    然后我们可以发现 (B(x)=mathbf {SET}(A)=e^{e^x-1})


    有向无环图计数

    给定正整数 (n) ,求恰好有 (n) 个点的带标号有向无环图的个数

    有向无环图 (DAG) 指的是一个无回路的有向图

    (f_i)(i) 个点有向无环图个数,一个简单的想法是枚举入度为 (0) 的点的大小

    [f_i=sum_{i=1}^ninom{n}{i}2^{i(n-i)}f_{n-i} ]

    注意到这时候我们实际上枚举的是至少有 (i) 个入度为 (0) 的点的大小,所以需要加上容斥系数

    [f_i=sum_{i=1}^ninom{n}{i}2^{i(n-i)}f_{n-i}(-1)^{i-1} ]

    考虑到利用生成函数,我们需要凑出关于多项式方程,构造左边有 (n) ,右边有 (n-i) 的项放到 (f(i)) 上,具体的

    [egin{aligned} &frac{f_n}{n!}=sum_{i=1}^nfrac{f_{n-i}}{(n-i)!}(sqrt2)^{n^2-i^2-(n-i)^2}frac{(-1)^{i-1}}{i!}\ &frac{f_n}{n!sqrt2^{n^2}}=sum_{i=1}^nfrac{f_{n-i}}{(n-i)!sqrt2^{(n-i)^2}}frac{1}{sqrt2^{i^2}} end{aligned} ]

    [F(x)=sum_{ige0}frac{f_i}{i!sqrt2^{n^2}}x^i,G(i)=sum_{ige0}frac{(-1)^{i-1}}{sqrt2^{i^2}}x^i ]

    可以得到 (F=FG+1) ,即 (F=frac{1}{G-1})

    (2mod p) 的二次剩余可以一开始暴力 (O(mod)) 求得


    边双连通图计数

    给定正整数 (n) ,求恰好有 (n) 个有标号点的边双连通图的个数。

    边双联通图是一个不存在桥的无向连通图

    (n) 个点的边双联通图的数量为 (b_n) ,生成函数为 (B(x))(n) 个点的有根联通图的数量为 (c_n) ,生成函数为 (C(x))

    显然有根联通图的生成函数 (C) 可以通过一般联通图求解

    对于任意有根连通图,进行边双连通分量缩点以后可以得到一棵树,不妨设原图的根节点所在的连通分量就是树的根节点,且这个连通分量的大小为 (n) ,则此联通分量对应的生成函数为 (frac{b_{n}x^n}{n!})

    然后根所在联通分量连接出去的其他边,边的另一端是一个联通图,将与这个边直接相连的点视为联通图的根,则这个联通图是一个有根联通图,由于边在原图根节点所在双连通分量的大小为 (n) ,且都可以作为边的一个端点,因此连出去的有根联通图的生成函数为 (nC(x))

    与根相连的边可以自由的存在,本质上是一个 (mathbf{SET}) ,因此所有与边相连的连通图的生成函数为 (e^{nC(x)})

    然后我们就可以建立 (B)(C) 的关系了,枚举根双连通块的大小,有

    [C(x)=sum_{nge 1}b_ne^{nC(n)}x^n ]

    因此

    [C(x)=B(xe^{c(x)}) ]

    (D(x)=xe^{c(x)})(D^{-1}(x)) 的为其的复合逆

    关于复合逆,回顾一下拉格朗日反演

    (G(F(x))=F(G(x))=x) ,则 (G)(F) 互为复合逆,由拉格朗日反演,我们有

    [[x^n]G(x)=frac{1}{n}[x^{n-1}](frac{x}{F(x)})^n\ [x^n]A(G(x))=frac{1}{n}[x^{n-1}]A'(x)(frac{x}{F(x)})^n ]

    因此

    [B(x)=C(D^{-1}(x)) ]

    求出 (C) 即可套用拉格朗日反演求出 (B) 某一项的值

  • 相关阅读:
    【Python】【元组】
    【Python】【列表】
    【Python】【序列】通用序列操作
    【Python】【数据结构】
    【Python】【字符串】常用方法
    【Python】【字符串】符号、对齐和用字符填充
    【Python】【字符串】替换字段
    @装饰器
    实现单点登录SSO
    supervisor 管理启动项目
  • 原文地址:https://www.cnblogs.com/butterflydew/p/11038342.html
Copyright © 2011-2022 走看看