• 斯特林数


    原文链接:https://www.cnblogs.com/ww3113306/p/10413829.html

    斯特林数

    • 斯特林数的内容主要参考自zzd大佬的博客
    • 在此基础上加上了一些自己的理解和补充内容。
    • 还没写完

    第一类斯特林数

    定义

    (S_1(n, m))表示(n)个点,组成(m)圆排列的方案数,记做(egin{bmatrix}n\mend{bmatrix}),递推公式为:

    [egin{bmatrix}n\kend{bmatrix} = (n - 1)egin{bmatrix}n - 1\kend{bmatrix} + egin{bmatrix}n - 1\k - 1end{bmatrix} ]

    理解:单独考虑新加入的第(n)个点。

    • (n)个点可以独立构成一个新的圆,因此只需要再加上前(n - 1)个点构成(k - 1)个圆的方案数(egin{bmatrix}n - 1\k - 1end{bmatrix}).
    • (n)个点可以插入原来有的任意一个圆中(不单独成圆)的任意一个点的左边,故有((n - 1)egin{bmatrix}n - 1\kend{bmatrix})种方案

    与阶乘的关系

    [n! = sum_{i = 0}^{n}egin{bmatrix}n\iend{bmatrix} ]

    证明:考虑其组合意义,一个排列对应一个置换,而一个置换会把(n)元素分成若干个置换环,其中每一种方案都对应一个置换。而我们把(n)个点分成若干个圆排列,就等价于把(n)个元素分成若干个置换环,因此我们枚举了把(n)个点分成若干个圆排列的方案数,就相当于枚举了置换的方案数。因此上式成立。

    与上升/下降次幂的关系

    下降次幂

    [x^{underline{n}} = sum_{i = 0}^n egin{bmatrix}n\iend{bmatrix}(-1)^{n - i}x^i ]

    (注意这个地方枚举从0开始和从1开始是等价的,因为(egin{bmatrix}n\0end{bmatrix} = 0))

    可以用数学归纳法证明:

    [x^{underline{n + 1}} = (x - n)x^{underline{n}} ]

    [= x cdot x^{underline{n}} - nx^{underline{n}} ]

    [= left( sum_{i = 0}^{n} egin{bmatrix}n\i end{bmatrix}(-1)^{n - i}x^{i + 1} ight ) - left(nsum_{i = 0}^{n} egin{bmatrix}n\iend{bmatrix} (-1)^{n - i}x^i ight) ]

    [= left(sum_{i = 1}^{n + 1}egin{bmatrix}n\i - 1 end{bmatrix}(-1)^{n - i + 1}x^i ight) - left(nsum_{i = 1}^{n + 1}egin{bmatrix}n\iend{bmatrix}(-1)^{n - i}x^i ight) ]

    [= sum_{i = 1}^{n + 1}left(egin{bmatrix}n\i - 1 end{bmatrix} + n egin{bmatrix}n\iend{bmatrix} ight)(-1)^{n - i + 1}x^i ]

    [= sum_{i = 1}^{n + 1}egin{bmatrix}n + 1\iend{bmatrix}(-1)^{n + 1 - i}x^i ]


    ####**上升次幂** $$x^{overline{n}} = sum_{i = 0}^{n}egin{bmatrix}n\kend{bmatrix}x^{k}$$ 相当于把下降次幂的式子中的-1给去掉了。 ##第一类斯特林数求法(分治FFT,倍增FFT) 最简单的当然就是直接根据递推式来求啦,但是有时候这样的复杂度不够优秀,因此我们需要一点更加优秀的求解方法。

    根据第一类斯特林数和上升次幂/下降次幂的关系,我们可以知道将特定的一些下降/上升次幂展开后系数的第(k)次项的绝对值就是要求的斯特林数的第(k)项。

    而上升/下降次幂可以看做一些多项式相乘(本身展开后就是多项式,而不同的上升/下降次幂可以通过合并不同的上升/下降次幂得到)

    分治FFT

    不会证,貌似要用生成函数?
    直接背下来吧,挺好背的。

    [prod_{i = 0}^{n - 1}(x + i) ]

    乘出来的多项式的第(k)项就是(egin{bmatrix}n\kend{bmatrix})

    倍增FFT

    因此我们考虑利用这2个式子来求斯特林数。
    为了方便,我们选择利用上升幂的式子:

    [f(x) = x^{overline{n}} = sum_{i = 0}^n egin{bmatrix} n\iend{bmatrix}x^i ]

    [ g(x) = (x + n)^{overline{n}} = sum_{i = 0}^{n} egin{bmatrix}n\iend{bmatrix}(x + n)^i ]

    那么我们有:

    [f(x)g(x) = (x + n)^{overline{2n}} = sum_{i = 0}^{2n} egin{bmatrix}2n\iend{bmatrix}(x + n)^i ]

    显然可以直接上分治FFT。
    但其实我们还有更加优秀的做法。

    考虑在分治FFT的基础上进行优化。
    思考一下为什么分治FFT是(nlog^2n)的?
    首先每一层的复杂度要计算(n)个点,一共有(logn)层,一共计算(nlogn)个元素,每个元素的复杂度是(logn)的,所以总复杂度(nlog^2n)

    (logn)层这个肯定没法优化,我们考虑优化每一层需要求解的点数.
    如果我们可以用同一层的前半部分快速求出后半部分,那么我们每次就只需要递归前半部分,那么我们就不用在每一层都对当前层所有的元素的计算,而只需要对一小块计算。

    因此我们考虑如何用前半部分快速计算后半部分。
    (此处为了书写方便,用(a_i)代替(egin{bmatrix} n\iend{bmatrix}))

    [g(x) = sum_{i = 0}^na_isum_{j = 0}^iinom{i}{j}n^{i - j}x^j ]

    换成枚举(x^i)

    [= sum_{i = 0}^nx^i left( sum_{j = i}^ninom{j}{i}n^{j - i}a_j ight) ]

    [= sum_{i = 0}^n left( sum_{j = i}^ninom{j}{i}n^{j - i}a_j ight)x_i ]

    我们只需要求出括号内的数是多少即可。

    [sum_{j = i}^ninom{j}{i}n^{j - i} a_j ]

    现在我们有

    [F(j - i) = inom{j}{i}n^{j - i} ]

    [G(j) = a_j ]

    (F)反转一下变成:

    [F(n - j + i + 1) = inom{j}{i}n^{j - i} ]

    这样(j + n - j + i + 1 = n + i + 1),是一个定值。
    虽然(n + i + 1 > n),但是因为数组中下标大于(n)的部分都是0,所以可以忽略。
    因此我们所要求的系数就是:

    [sum_{j = i}^ninom{j}{i}n^{j - i}a_j = (F*G)(n + i + 1) ]

    因此我们做一遍FFT就可以得到(g)的系数了

    那么这样计算的话,一共会计算多少元素呢?

    [n + frac{n}{2} + frac{n}{4} + ... + frac{n}{n} ]

    (O(n))级别的!
    因为对每个点进行计算的复杂度仍然是(logn)级别的,所以我们的总复杂度就可以做到(nlogn)
    更形象化的,这2个算法的区别可以这样描述:
    分治FFT和倍增FFT对比图.png-4.9kB
    考虑到后者其实是在用1个点,不断的乘2,最后得到整个序列。因此我们将它称之为倍增FFT。

    第二类斯特林数

    定义

    (S_2(n, m))表示(n)个元素分成(m)个集合的方案数,记做(left{egin{array}{c}n\mend{array} ight})
    递推式为:

    [left{egin{array}{c}n\mend{array} ight} = left{egin{array}{c}n - 1\m - 1end{array} ight} + mleft{egin{array}{c}n - 1\mend{array} ight} ]

    理解:考虑第(n)个元素放在哪里,

    • (n)个元素可以独立构成一个新集合,因此方案数为(left{egin{array}{c}n - 1\m - 1end{array} ight}).
    • (n)个元素可以加入之前的任意一个集合中,因此方案数为(left{ egin{array}{c}n - 1 \mend{array} ight})

    重要式子

    [x^n = sum_{k = 0}^n left{ egin{array}{c} n \ k end{array} ight} x^{underline{k}} ]

    证明:还是用归纳法。。。

    求解

    一个式子:

    [m!left{ egin{array}{c}n\mend{array} ight} = sum_{k = 0}^m inom{m}{k}k^n(-1)^{m - k} ]

    证明:用递推式证明.
    于是令

    [f(k) = inom{m}{k}k^n, quad g(m - k) = (-1)^{m - k} ]

    然后用FFT算算就好了。

    广义斯特林数

    [left{ egin{array}{c}n\kend{array} ight} = egin{bmatrix}-k\-nend{bmatrix} ]

    扩展/总结

    来源1

    基本式子

    [egin{bmatrix}n\kend{bmatrix} = (n - 1)egin{bmatrix}n - 1\kend{bmatrix} + egin{bmatrix}n - 1\k - 1end{bmatrix} ]

    [left{egin{array}{c}n\mend{array} ight} = left{egin{array}{c}n - 1\m - 1end{array} ight} + mleft{egin{array}{c}n - 1\mend{array} ight} ]

    [n! = sum_{i = 0}^n egin{bmatrix}n\iend{bmatrix} ]

    [left{ egin{array}{c}n\kend{array} ight} = egin{bmatrix}-k\-nend{bmatrix} ]

    特殊值

    [left{egin{array}{c}n\0end{array} ight} = egin{bmatrix}n\0end{bmatrix} = [n == 0] ]

    [left{egin{array}{c}n\1end{array} ight} = [n > 0] ]

    [egin{bmatrix}n\1end{bmatrix} = (n - 1)![n > 0] ]

    [left{egin{array}{c}n\2end{array} ight} = (2^{n - 1} - 1)[n > 0] ]

    [egin{bmatrix}n\2end{bmatrix} = (n - 1)!left(sum_{i = 1}^{n - 1} frac{1}{i} ight)[n > 0] ]

    [left{egin{array}{c}n\n - 1end{array} ight} = egin{bmatrix}n\n - 1end{bmatrix} = inom{n}{2} ]

    [left{egin{array}{c}n\nend{array} ight} = egin{bmatrix}n\nend{bmatrix} = inom{n}{n} = 1 ]

    [left{egin{array}{c}n\kend{array} ight} = egin{bmatrix}n\kend{bmatrix} = inom{n}{k} = 0, k > n ]

    各种幂相关

    [x^n = sum_{k = 0}^nleft{egin{array}{c}n\kend{array} ight}x^{underline{k}} = sum_{k = 1}^nleft{egin{array}{c}n\kend{array} ight}(-1)^{n - k}x^{overline{k}} ]

    [x^{underline{n}} = sum_{k = 0}^{n}egin{bmatrix}n\kend{bmatrix}(-1)^{n - k}x^k ]

    [x^{overline{n}} = sum_{k = 0}^negin{bmatrix}n\kend{bmatrix}x^k ]

    反转公式

    [sum_{k = 1}^n egin{bmatrix}n\kend{bmatrix}left{egin{array}{c}k\mend{array} ight}(-1)^{n - k} = [n == m] ]

    [sum_{k = 1}^nleft{egin{array}{c}n\kend{array} ight} egin{bmatrix}k\mend{bmatrix}(-1)^{n - k} = [n == m] ]

    其他恒等式

    [left{egin{array}{c}n + 1\m + 1end{array} ight} = sum_{k = 1}^n inom{n}{k} left{egin{array}{c}k\mend{array} ight} ]

    [egin{bmatrix} n + 1\ m + 1end{bmatrix} = sum_{k = 1}^n egin{bmatrix}n\kend{bmatrix} inom{k}{m} ]

    [left{egin{array}{c}n\mend{array} ight} = sum_{k = 1}^ninom{n}{k}left{egin{array}{c}k + 1\m + 1end{array} ight}(-1)^{n - k} ]

    [egin{bmatrix}n\mend{bmatrix} = sum_{k = 1}^n egin{bmatrix}n + 1\k + 1end{bmatrix} inom{k}{m}(-1)^{m - k} ]

    [m!left{egin{array}{c}n\mend{array} ight} = sum_{k = 1}^ninom{m}{k}k^n(-1)^{m - k} ]

    [left{egin{array}{c}n + 1\m + 1end{array} ight} = sum_{k = 0}^n left{egin{array}{c}k\mend{array} ight}(m + 1)^{n - k} ]

    [egin{bmatrix}n + 1\m + 1end{bmatrix} = sum_{k = 0}^n egin{bmatrix}k\mend{bmatrix}n^{underline{n - k}} = n!sum_{k = 0}^n frac{egin{bmatrix}k\mend{bmatrix}}{k!} ]

    [left{egin{array}{c}m + n + 1\mend{array} ight} = sum_{k = 0}^mkleft{egin{array}{c}n + k\kend{array} ight} ]

    [egin{bmatrix}m + n + 1\mend{bmatrix} = sum_{k = 0}^m(n + k)egin{bmatrix}n + k\kend{bmatrix} ]

    [inom{n}{m} = sum_{k = 1}^nleft{egin{array}{c}n + 1\k + 1end{array} ight} egin{bmatrix}k\mend{bmatrix}(-1)^{m - k} ]

    [n^{underline{n - m}}[n geq m] = sum_{k = 1}^n egin{bmatrix} n + 1\k + 1end{bmatrix}left{egin{array}{c}k\mend{array} ight}(-1)^{m - k} ]

    [left{egin{array}{c}n\n - mend{array} ight} = sum_{k = 1}^n inom{m - n}{m + k} inom{m + n}{n + k} egin{bmatrix}m + k \ kend{bmatrix} ]

    [egin{bmatrix}n\n - mend{bmatrix} = sum_{k = 1}^n inom{m - n}{m + k} inom{m + n}{n + k}left{egin{array}{c}m + k\kend{array} ight} ]

    [left{egin{array}{c}n\l + mend{array} ight} inom{l + m}{l} = sum_{k = 1}^nleft{egin{array}{c}k\lend{array} ight} left{egin{array}{c}n - k\mend{array} ight} inom{n}{k} ]

    [egin{bmatrix}n \ l + mend{bmatrix} inom{l + m}{l} = sum_{k = 1}^n egin{bmatrix}k\lend{bmatrix} egin{bmatrix}n - k\mend{bmatrix}inom{n}{k} ]

  • 相关阅读:
    java实现第九届蓝桥杯最大乘积
    java实现第九届蓝桥杯最大乘积
    Anaconda入门使用指南
    Java安全——密钥那些事
    关于keyGenerator,KeyPairGenerator,SecretKeyFactory的解析
    @Transactional事务几点注意
    三种方式都是通过某种公开的算法将原始信息进行编码 /加密
    信息摘要算法 MessageDigestUtil
    Java使用RSA加密解密签名及校验
    java util
  • 原文地址:https://www.cnblogs.com/ww3113306/p/10413829.html
Copyright © 2020-2023  润新知