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

    我们定义序列 (a) 的普通型生成函数 (( m OGF)) 为形式幂级数:

    [F(x) = sumlimits_{n ge 0} a_n x ^ n ]

    之所以要构造这样一个形式幂级数,是因为当 (|x| < 1) 的时候往往可以收敛成一个封闭形式便于运算。


    下面是几个常见的 ( m OGF) 极其封闭形式:

    1. (F_1(x) = sumlimits_{n ge 0} x ^ n = 1 + x + x ^ 2 + x ^ 3 + cdots = dfrac{1}{1 - x})

    可以发现这是一个公比为 (x) 的等比数列,对于 (G(x) = sumlimits_{i = 0} ^ n x_i = 1 + x + x ^ 2 + cdots + x ^ n)

    根据等比数列求和公式有 (G(x) = dfrac{1 - x ^ {n + 1}}{1 - x}),因此可知 (F_1(x) = dfrac{1 - x ^ infty}{1 - x})

    根据上面所提到的,(|x| < 1)(x ^ infty) 收敛于 (0),故 (F_1(x) = dfrac{1}{1 - x})

    于是对于一般的公比为 (ax) 的等比数列构成的 ( m OGF),有:

    (F_2(x) = sumlimits_{n ge 0} a ^ n x ^ n = dfrac{1}{1 - ax})

    于是得到第二种常用的 ( m OGF)

    1. (F_2(x) = sumlimits_{n ge 0} ba ^ n x ^ n = b + bax + ba ^ 2x ^ 2 + cdots = dfrac{b}{1 - ax})

    2. (F_3(x) = sumlimits_{n ge 0} n x ^ n = 1 + 2x + 3x + cdots = dfrac{1}{(1 - x) ^ 2})

    从形式上看可以发现 (F_3(x) = F_1 ^ 2(x)),事实上有:

    [F_3(x) = sumlimits_{n ge 0} sumlimits_{i = 0} ^ n x ^ i imes x ^ {n - i} = sumlimits_{n ge 0} n x ^ n ]

    1. (F_{4_m}(x) = sumlimits_{n ge 0} inom{m}{n} x ^ n = (x + 1) ^ m)

    运用二项式定理不难证明。

    1. (F_{5_m}(x) = sumlimits_{n ge 0} inom{m + n}{n} x ^ n = dfrac{1}{(1 - x) ^ {m + 1}})

    注意到

    [sumlimits_{i = m - 1} ^ {n + m - 1} inom{m - 1 + (i - m + 1)}{i - m + 1} = inom{n + m}{n} ]

    (F_{5_m}(x))(x ^ n) 的系数为 (F_{5_{m - 1}})(x_0 sim x ^ n) 系数之和,由 (F_3(x)) 的经验不难发现:

    [F_{5_m}(x) = F_{5_{m - 1}}(x) imes F_1(x) ]

    特别的,(m = 0)(F_{5_0}(x) = F_1(x)),带入不难得证。


    为了下面内容的推进,我们引入牛顿二项式定理:

    实质上 (dbinom{n}{m} = dfrac{n ^ {underline m}}{m!}) 可以看作是一种数值上的运算,那么我们不妨扩充组合数的定义域至复数域,有:

    [dbinom{n}{m} = dfrac{n ^ {underline m}}{m!}(n in mathbf{C}, m in mathbf{N}) ]

    [(1 + x) ^ n = sumlimits_{m ge 0} dbinom{n}{m}x ^ m(n in mathbf{C}) ]

    同时,借助其我们也能证明第五种常见 ( m OGF)

    [egin{aligned} F_{5_m}(x) &= (1 - x) ^ {-(m + 1)} \ &= sumlimits_{n ge 0} inom{-(m + 1)}{n} (-x) ^ n \ &= sumlimits_{n ge 0} (-1) ^ n frac{-(m + 1) imes -(m + 2) cdots imes -(m + n)}{n!} x ^ n \ &= sumlimits_{n ge 0}frac{(m + n)!}{n!m!} x ^ n \ &= sumlimits_{n ge 0} dbinom{m + n}{n} x ^ n end{aligned} ]


    下面简单介绍一些生成函数的基本应用。

    求解递推数列通项公式

    1. 有限项数递推式

    以斐波那契数列为例,令 (a_0 = 0, a_1 = 1, a_n = a_{n - 1} + a_{n - 2}(n ge 2))

    令其 ( m OGF)(F(x) = sumlimits_{n ge 0} a_n x ^ n)

    根据斐波那契数列递推公式,可知:

    [xF(x) + x ^ 2F(x) + x = F(x) ]

    解关于 (F(x)) 的方程组可得:

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

    那么只需要求出 (dfrac{x}{1 - x - x ^ 2}) 展开式在 (x ^ n) 处的系数即可。

    介于我们只知道 (dfrac{b}{1 - ax}) 的展开式,因此可以考虑将 (F(x)) 拆成两个形如 (dfrac{b}{1 - ax}) 的和。

    不妨设

    [frac{x}{1 - x - x ^ 2} = frac{B_1}{1 - A_1x} + frac{B_2}{1 - A_2x} ]

    待定系数解得:

    [egin{cases} B_1 = frac{1}{sqrt{5}} \ B_2 = -frac{1}{sqrt{5}} \ A_1 = frac{1 + sqrt{5}}{2} \ A_2 = frac{1 - sqrt{5}}{2} end{cases} ]

    利用常见 ( m OGF 2) 即可计算出通项公式:

    [a_n = dfrac{1}{sqrt{5}}((dfrac{1 + sqrt{5}}{2}) ^ n - (dfrac{1 - sqrt{5}}{2}) ^ n) ]

    一般地,对于封闭形式为分数形式且分子分母均为两个多项式的情况,可用类似的方式求解通向公式。

    1. 另一类递推式

    以卡特兰数为例。

    (a_0 = a_1 = 1, a_n = sumlimits_{i = 0} ^ {n - 1} a_i imes a_{n - i - 1}(n ge 2))

    令其 ( m OGF)(F(x) = sumlimits_{n ge 0} a ^ n x ^ n)

    不难发现其递推式是一个卷积的形式,于是有:

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

    解之得:

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

    要保留哪个根呢?

    求解上式在 (x o 0) 时的极限可以发现,当 (F(x) = dfrac{1 + sqrt{1 - 4x}}{2x}) 时不收敛。

    原因是:

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

    则有:

    [limlimits_{x o 0 ^ {+}} frac{2}{1 - sqrt{1 - 4x}} = infty ]

    [limlimits_{x o 0 ^ {-}} frac{2}{1 - sqrt{1 - 4x}} = -infty ]

    故此时 (x o 0) 时极限不存在。

    因此可以得到:

    [F(x) = dfrac{1 - sqrt{1 - 4x}}{2x} ]

    将分子部分单独拿出来考虑,令 (G(x) = 1 - sqrt{1 - 4x} = 1 - (1 - 4x) ^ {frac{1}{2}}),使用牛顿二项式定理展开:

    [egin{aligned} G(x) &= 1 - sumlimits_{n ge 0} dbinom{frac{1}{2}}{n} (-4x) ^ n \ &= 1 - sumlimits_{n ge 0} frac{frac{1}{2} ^ {underline n}}{n!} (-4x) ^ n \ &= 1 - sumlimits_{n ge 0} frac{frac{1}{2} imes (-frac{1}{2}) imes (-frac{3}{2}) imes cdots imes (-frac{2n - 3}{2})}{n!} (-4x) ^ n \ end{aligned} ]

    特别要注意的是 (dbinom{frac{1}{2}}{0} = frac{frac{1}{2} ^ 0}{0!} = 1) 但是用上面哪个式子是不正确的,因此需要特别考虑:

    [egin{aligned} G(x) &= sumlimits_{n ge 1} (-1) ^ {2n - 1} frac{(2n - 3)!!}{n!2 ^ n} (4x) ^ n \ &= sumlimits_{n ge 1} frac{(2n - 2)!}{n!(2n - 2)!!2 ^ n} (4x) ^ n \ &= sumlimits_{n ge 1} frac{2(2n - 2)!}{n!(n - 1)!} x ^ n \ &= sumlimits_{n ge 1} frac{dbinom{2n - 1}{n}}{2n - 1} 2x ^ n end{aligned} ]

    带回原式有:

    [egin{aligned} F(x) &= frac{sumlimits_{n ge 1} frac{dbinom{2n - 1}{n}}{2n - 1} 2x ^ n}{2x} \ &= sumlimits_{n ge 0} frac{dbinom{2n + 1}{n + 1}}{2n + 1} x ^ n \ &= sumlimits_{n ge 0} frac{dbinom{2n}{n}}{n + 1} x ^ n end{aligned} ]

    因此可知 (a_n = dfrac{dbinom{2n}{n}}{n + 1})


    下面是几道基本例题。

    A(参见 ( m OI-Wiki))

    求解一类计数问题。

    不妨写出 (1 sim 8)( m OGF)

    (F_1(x) = 1 + x ^ 2 + x ^ 4 + cdots = sumlimits_{n ge 0} x ^ {2n} = dfrac{1}{1 - x ^ 2})

    (F_2(x) = 1 + x = dfrac{1 - x ^ 2}{1 - x})

    (F_3(x) = 1 + x + x ^ 2 = dfrac{1 - x ^ 3}{1 - x})

    (F_4(x) = x + x ^ 3 + cdots = sumlimits_{n ge 0} x ^ {2n + 1} = dfrac{x}{1 - x ^ 2})

    (F_5(x) = 1 + x ^ 4 + x ^ 8 + cdots = sumlimits_{n ge 0} x ^ {4n} = dfrac{1}{1 - x ^ 4})

    (F_6(x) = 1 + x + x ^ 2 + x ^ 3 = dfrac{1 - x ^ 4}{1 - x})

    (F_7(x) = F_2(x))

    (F_8(x) = 1 + x ^ 3 + x ^ 6 + cdots = sumlimits_{n ge 0} x ^ {3n} = dfrac{1}{1 - x ^ 3})

    将这八个 ( m OGF) 相乘即可得到总的 ( m OGF)

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

    根据常用 ( m OGF 5) 可知:

    [F(x) = sumlimits_{n ge 1} dbinom{n + 2}{n - 1} x ^ n ]

    B

    可知第 (i) 种糖果的 ( m OGF)(F_i(x) = 1 + x + cdots x ^ {m_i} = dfrac{1 - x ^ {m_i + 1}}{1 - x})

    (n) 种糖果的 ( m OGF) 相乘可得总的 ( m OGF)

    [F(x) = frac{prodlimits_{i = 1} ^ n{1 - x ^ {m_i + 1}}}{(1 - x) ^ n} ]

    介于要统计某个区间内的系数,首先差分转化为统计一个前缀的系数和。

    由之前的经验不难发现只需要让 (F(x)) 卷上 (F_1(x)) 即可只统计单点的系数了。

    于是只需要考虑:

    [F(x) = frac{prodlimits_{i = 1} ^ n1 - x ^ {m_i + 1}}{(1 - x) ^ {n + 1}} ]

    (x ^ L) 处的系数即可。

    将分子分母单独考虑:

    [F(x) = (prodlimits_{i = 1} ^ n 1 - x ^ {m_i + 1}) imes sumlimits_{m ge 0} dbinom{n + m}{m} x ^ m ]

    注意到 (n) 很小,只需暴力展开前面的多项式再乘上对应贡献即可。可以使用 (dfs) 来实现暴力展开。

    需要注意的是,模数为 (2004) 不为质数,可能不存在逆元,因此计算组合数 (dbinom{n}{m}) 的时候先将分子对 (m!P) 取模,最后除以 (m!) 即可。(易证得此方法正确)

    C

    不难发现对于峰顶左右两边是互不影响的两个子问题,于是可以考虑枚举峰顶大小和峰顶位置,分别计算左右两边的方案。

    但如果出现多个位置均为峰顶的情况,这样会记重,于是只能枚举峰顶的两端。

    其次来考虑一下左右两边的子问题:在 ([1, m]) 中选择 (n) 个数形成不降序列的方案数。

    直接计数是不好计算的,可以考虑统计差值的方案数,即 (x_1 + x_2 + cdots x_n = L(x_i ge 0)) 的方案数。

    因为 (x_1, x_n) 强制大于 (0) 于是先将这部分减去即可:

    [dbinom{n + m - 3}{m - 2} ]

    那么最终的答案就为:

    [sumlimits_{i = 1} ^ m sumlimits_{j = 1} ^ n sumlimits_{k = j} ^ n dbinom{j + i - 3}{i - 2} imes dbinom{n - k + i - 2}{i - 2} ]

    需要注意的是 (0 - 2 = -1 < 0)(i = 1) 的情况显然只有全 (1) 一种,特殊考虑即可,下面只考虑 (i > 2) 的情况。

    [sumlimits_{i = 2} ^ m sumlimits_{j = 1} ^ n sumlimits_{k = j} ^ n dbinom{j + i - 3}{i - 2} imes dbinom{n - k + i - 2}{i - 2} ]

    首先平移值域将常数项去掉:

    [sumlimits_{i = 0} ^ {m - 2} sumlimits_{j = 0} ^ {n - 1} sumlimits_{k = j + 1} ^ n dbinom{j + i}{i} imes dbinom{n - k + i}{i} ]

    [egin{aligned} &= sumlimits_{i = 0} ^ {m - 2} sumlimits_{j = 0} ^ {n - 1} dbinom{j + i}{i} sumlimits_{k = j + 1} ^ n imes dbinom{n - k + i}{i} \ &= sumlimits_{i = 0} ^ {m - 2} sumlimits_{j = 0} ^ {n - 1} dbinom{j + i}{i} imes dbinom{n - j + i}{i + 1} \ &= sumlimits_{i = 0} ^ {m - 2} sumlimits_{j = 0} ^ {n - 1} dbinom{i + j}{j} imes dbinom{(i + 1) + (n - j - 1)}{n - j - 1} \ end{aligned} ]

    不难发现,后面两个组合数分别为 (F_{5_i}(x))(x ^ j) 处的系数和 (F_{5_{i + 1}}(x))(x ^ {n - j - 1}) 处的系数。

    并且,整个后面可以明显发现为一个卷积的形式,因此可知后面一整块式子相当于为 ( m OGF)

    [F(x) = F_{5_i}(x) imes F_{5_{i + 1}}(x) = frac{1}{(1 - x) ^ {2i + 3}} ]

    (x ^ {n - 1}) 的系数,即为:(dbinom{2i + n + 1}{n - 1})

    因此最终的答案为:

    [1 + sumlimits_{i = 0} ^ {m - 2} dbinom{2i + n + 1}{n - 1} ]

  • 相关阅读:
    线程池
    单例设计模式
    String,StringBuffer,StringBuilder
    马踏棋盘算法
    最短路径问题 (迪杰斯特拉算法,弗洛伊德算法)
    最小生成树 修路问题(普里姆算法,克鲁斯卡尔算法)
    贪心算法 求解集合覆盖问题
    Stream 数组转换
    unittest与pytest对比
    条件编译
  • 原文地址:https://www.cnblogs.com/Go7338395/p/14191085.html
Copyright © 2011-2022 走看看