• 学习总结:斯特林数( Stirling number )


    基本定义

    第一类斯特林数:$1 dots n$的排列中恰好有$k$个环的个数;或是,$n$元置换可分解为$k$个独立的轮换的个数。记作

    $$ egin{bmatrix} n \ k end{bmatrix}. $$

    第二类斯特林数:将$n$个元素分成$k$个非空集合的方案数。记作

    $$ egin{Bmatrix} n \ k end{Bmatrix}. $$

    根据定义,我们有

    $$ sum_{k=0}^n egin{bmatrix} n \ k end{bmatrix} = n!, $$

    $$ sum_{k=0}^n egin{Bmatrix} n \ k end{Bmatrix} = B_n, $$

    其中$B_n$是 Bell 数

    递推关系

    第一类斯特林数:考虑$egin{bmatrix} n \ k end{bmatrix}$。枚举第$n$个元素,其若自成一个环,则有$egin{bmatrix} n-1 \ k-1 end{bmatrix}$种方案;若其放在已有的某个环中,则有$n-1$个位置可放,于是有$(n-1)egin{bmatrix} n-1 \ k end{bmatrix}$种方案。因此,

    $$ egin{bmatrix} n \ k end{bmatrix} = (n-1)egin{bmatrix} n-1 \ k end{bmatrix} + egin{bmatrix} n-1 \ k-1 end{bmatrix}. $$

    第二类斯特林数:考虑$egin{Bmatrix} n \ k end{Bmatrix}$。枚举第$n$个元素,若其自成一份,则有$egin{Bmatrix} n-1 \ k-1 end{Bmatrix}$种方案;若其放在已有的某份,则有$k$份可选择,于是有$kegin{Bmatrix} n-1 \ k end{Bmatrix}$种方案。因此,

    $$ egin{Bmatrix} n \ k end{Bmatrix} = kegin{Bmatrix} n-1 \ k end{Bmatrix} + egin{Bmatrix} n-1 \ k-1 end{Bmatrix}. $$

    以上递推式,可在$O(nk)$的复杂度内求出斯特林数。

    斯特林数与阶乘幂

    我们定义下降幂(Falling Factorial):

    $$ x^{underline{n}} = x(x-1)cdots (x-n+1). $$

    以及上升幂(Rising Factorial):

    $$ x^{overline{n}} = x(x+1)cdots (x+n-1). $$

    则有以下等式:

    $$
    egin{aligned}
    x^{underline{n}} = sum_{k=0}^n (-1)^{n-k} egin{bmatrix} n \ k end{bmatrix} x^k  & Longleftrightarrow x^n = sum_{k=0}^n egin{Bmatrix} n \ k end{Bmatrix} x^{underline{k}} \
    x^{overline{n}} = sum_{k=0}^n egin{bmatrix} n \ k end{bmatrix} x^k  & Longleftrightarrow x^n = sum_{k=0}^n (-1)^{n-k} egin{Bmatrix} n \ k end{Bmatrix} x^{overline{k}} \
    x^{overline{n}} = sum_{k=0}^n L(n, k) x^{underline{k}}  & Longleftrightarrow x^{underline{n}} = sum_{k=0}^n (-1)^{n-k} L(n, k) x^{overline{k}} 
    end{aligned}
    $$

    其中

    $$ L(n, k) = sum_j egin{bmatrix} n \ j end{bmatrix} egin{Bmatrix} j \ k end{Bmatrix} = inom{n-1}{k-1} frac {n!} {k!}. $$

    注:最常用的是将$x^n$分成若干个$x^{underline{k}}$之和,或者是$inom{x}{k}$之和,即

    $$ x^n = sum_{k=0}^n egin{Bmatrix} n \ k end{Bmatrix} x^{underline{k}} = sum_{k=0}^n k! egin{Bmatrix} n \ k end{Bmatrix} inom{x}{k}. $$

    斯特林反演

    斯特林数和阶乘幂的关系可推广至一般函数:

    $$
    egin{aligned}
    g(n) = sum_{k=0}^n (-1)^{n-k} egin{bmatrix} n \ k end{bmatrix} f(k)  & Longleftrightarrow f(n) = sum_{k=0}^n egin{Bmatrix} n \ k end{Bmatrix} g(k) \
    g(n) = sum_{k=0}^n L(n, k) f(k) & Longleftrightarrow f(n) = sum_{k=0}^n (-1)^{n-k} L(n, k) g(k) 
    end{aligned}
    $$

    斯特林数的快速求解

    第一类斯特林数

    为快速计算$egin{bmatrix} n \ k end{bmatrix}$,我们利用

    $$ x^{overline{n}} = sum_{k=0}^n egin{bmatrix} n \ k end{bmatrix} x^k. $$

    令$f(x) = x^{overline{n}}, g(x) = (x+n)^{overline{n}}$,则$f(x)g(x) = x^{overline{2n}}$。注意到$f(x)$中$x^k$的系数对应了$egin{bmatrix} n \ k end{bmatrix}$。若求得了$g(x)$,计算$f(x)$与$g(x)$的多项式乘积即可得到$egin{bmatrix} 2n \ cdot end{bmatrix}$。而求$g(x)$的方法如下:

    $$ f(x) = sum_{k=0}^n a_k x^k, $$

    $$
    egin{aligned}
    g(x)
    & = sum_{k=0}^n a_k (x+n)^k \
    & = sum_{k=0}^n a_k sum_{i=0}^k inom{k}{i} n^{k-i} x^i \
    & = sum_{k=0}^n frac{1} {(n-k)!} x^{n-k} sum_{i+j=k} frac{n^i}{i!} a_{n-j} (n-j)!
    end{aligned}
    $$

    就变成了卷积计算。用快速傅里叶变换则计算$g(x)$的时间复杂度为$O(n log n)$。

    总的时间复杂度为

    $$ T(n) = T(n/2)+O(nlog n), $$

    解为$T(n) = O(n log n)$。

    第二类斯特林数

    我们仍可用第一类斯特林数的做法并利用

    $$ x^n = sum_{k=0}^n egin{Bmatrix} n \ k end{Bmatrix} x^{underline{k}}. $$

    但我们有一个更好的选择:

    $$ egin{Bmatrix} n \ k end{Bmatrix} = frac 1 {k!} sum_{i=0}^k (-1)^{k-i} inom{k}{i} i^n = sum_{i+j=k} frac{i^n}{i!} frac{(-1)^j}{j!}. $$

    就变成了卷积计算,用快速傅里叶变换则时间复杂度为$O(n log n)$。

    一些例题

    CodeForces 932E. Team Work

    HDU 4625. JZPTREE

    CodeForces 1097G. Vladislav and a Great Legend

    CodeForces 960G. Bandit Blues

  • 相关阅读:
    带有头结点的链表的基本操作
    转:gdb相关学习
    wareshark网络协议分析之ARP
    wareshark网络协议分析之DHCP
    java多线程(内附实例:窗口售票问题、人和叉子的问题)
    Android深度探索(卷1)HAL与驱动开发 虚拟环境的安装
    source insigt、pc-lint、VS联合使用
    java arrays类学习
    C#函数重载
    (转)Pycharm用鼠标滚轮控制字体大小
  • 原文地址:https://www.cnblogs.com/TinyWong/p/10435831.html
Copyright © 2020-2023  润新知