zoukankan      html  css  js  c++  java
  • 斯特林数 学习笔记

    本文为博主原创,转载请标明出处。

    斯特林数 学习笔记

    原文链接https://www.cnblogs.com/zhouzhendong/p/Stirling-Number.html 

    $ ewcommand{strb}[2]{left { egin{matrix}{#1}\{#2}end{matrix} ight }} ewcommand{stra}[2]{left [ egin{matrix}{#1}\{#2}end{matrix} ight ] } ewcommand{ino}[2]{left ( egin{matrix}{#1}\{#2}end{matrix} ight ) } ewcommand{udl}{underline} ewcommand{ovl}{overline}$

    第一类斯特林数

    定义

      $S_1(n,m)$ 表示 $n$ 个元素,排成 $m$ 个轮换的方案数,记做 $stra nm$ 。递推公式为:

    $$stra{n}{k}=(n-1)stra{n-1}{k}+stra{n-1}{k-1}$$

    ​  可以通过其组合意义来理解:用 $n$ 个元素构成 $k$ 个轮换,其中,第 $n$ 个元素可以独立构成一个新的轮换,有 $stra {n-1}{k-1}$ 种方案;也可以插入到原有的轮换中,可以插入到之前的任意一个元素的左边,故有 $(n-1)stra {n-1}k$ 种方案。

    从组合意义出发证明一个式子

      证明

    $$n! = sum_{i=0}^{n} stra{n}{i}$$

      解: 考虑其组合意义。一个排列,唯一地对应了一个置换:

    $$ egin{pmatrix} 1&2&3&4&cdots&n\ p_1&p_2&p_3&p_4&cdots &p_n end{pmatrix} $$

     

      而一个置换,唯一地对应了一组轮换。例如排列 $(1,5,3,2,4)$ ,就可以看做轮换组 $[1][2,5,4][3]$ 。如果两个排列不同,那么他们对应的轮换中,必然有一个元素的下一个元素不同,故排列与轮换一一对应。而原式右侧的式子正是有 $0$~$n$ 个轮换的方案数,就等价于左边。

    证明一个重要式子

      证明

    $$x^udl{n}= sum_{i=0}^{n} stra ni(-1)^{n-i} x^i ag{1}$$

      解:利用数学归纳法以及推式子:

    $$ egin{eqnarray*} x^udl {n+1} &=& (x-n) x^udl n\ &=& xcdot x^udl n - n x^udl n\ &=& left ( sum_{i=0}^n stra ni (-1)^{n-i} x^{i+1} ight ) - left (nsum_{i=0}^n stra ni (-1)^{n-i} x^i ight )\ &=& left ( sum_{i=1}^{n+1} stra n{i-1} (-1)^{n-i-1} x^i ight ) - left (nsum_{i=1}^{n+1} stra ni (-1)^{n-i} x^i ight )\ &=&sum_{i=1}^{n+1}left (stra n{i-1} + n stra ni ight )(-1)^{n+1-i}x^i\ &=&sum_{i=1}^{n+1}stra {n+1}{i} (-1)^{n+1-i} x^i end{eqnarray*} $$

    ​  至此,得证。

      这个式子为何重要呢?是因为它告诉我们斯特林数和下降幂有关系!下降幂展开后,所有系数的绝对值就是一行斯特林数。

    求第一类斯特林数

      现在要求你求出所有 $S_1(n,i)_{|iin [0,n]}$ 。

      如果 $n$ 不大,显然可以直接通过定义式来求。但是 $n$ 如果比较大呢?

      在对于 $(1)$ 的证明中,我们知道了下降幂的每一项系数在数值上面等于斯特林数。所以我们只需要求出下降幂就可以了。

      直接分治 FFT 显然可以做到 $O(nlog^2 n)$ 的时间复杂度。现在我们来考虑另一种做——倍增法:

      为了避免各种 $-1$ 系数的烦恼,我们用上升幂来求斯特林数。

    ​  假设 $f(x) = x^ovl n ,g(x)=(x+n)^ovl n$ ,则 $f(x)g(x)=x^ovl{2n}$ 。我们需要做的仅仅是通过 $f(x)$ 来快速地求 $g(x)$ 。于是:

    $$ 设 f(x)=sum_{i=0}^n a_i x^i \ egin {eqnarray*} 则g(x)&=&sum_{i=0}^n a_i (x+n)^i \ &=& sum_{i=0}^n a_i sum_{j=0}^i ino ij n^{i-j} x^j\ &=& sum_{i=0}^n left (sum_{j=i}^n ino ji n^{j-i} a_j ight )x^i end {eqnarray*} $$

      这个东西显然是一个卷积。直接算就好了。于是总的时间复杂度为

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

     

    第二类斯特林数

    定义

      $s_2(n,m)$ 表示 $n$ 个元素分成 $m$ 个集合的方案数,记做 $strb nm$ 。递推公式为:

    $$strb nm = strb {n-1}{m-1} + mstrb {n-1}{m}$$

      从组合意义理解:考虑第 $n$ 个元素的摆放方式。第 $n$ 个元素可以独立构成一个新的集合,方案数是 $strb {n-1}{m-1}$ ;也可以加入到原有的集合中,方案数是 $mstrb {n-1}m$ 。

    证明一个重要式子

      证明

    $$x^n = sum_{k=0}^{n} strb nk x^udl{k}$$

      解

    $$egin {eqnarray*} x^n &=& sum_{k=0}^{n} strb nk x^udl{k}\ x^n &=& x cdot x^{n-1} \ &=&x sum_{i=0}^{n-1} strb{n-1}{i} x^udl i\ &=&sum_{i=0}^{n-1} strb{n-1}{i} (x^udl {i+1}+ix^udl i) \ &=&sum_{i=0}^{n-1} strb{n-1}{i} x^udl {i+1}+sum_{i=0}^{n-1} strb{n-1}{i}ix^udl i \ &=&sum_{i=0}^{n} strb{n-1}{i-1} x^udl {i}+sum_{i=0}^{n-1} strb{n-1}{i}ix^udl i \ &=&sum_{i=0}^{n} left ( strb{n-1}{i-1}+istrb {n-1}i ight ) x^udl i\ &=&sum_{i=0}^{n} strb ni x^udl{i} end {eqnarray*}$$

      这个式子说明了第二类斯特林数也和下降幂、整数幂有关系。

    如何求第二类斯特林数

      首先证明这个式子:

    $$ egin{eqnarray*} m!strb nm &=& sum_{k=0}^m ino mk k^n (-1)^{m-k}\ 解:strb nm &=& strb {n-1}{m-1} + mstrb {n-1}m\ &=& sum_{k=0}^{m-1} cfrac {ino {m-1}{k}k^{n-1}(-1)^{m-1-k}}{(m-1)!} + msum_{k=0}^{m} cfrac {ino{m}{k}k^{n-1}(-1)^{m-k}}{m!}\ &=& sum_{k=0}^{m} cfrac {ino {m-1}{k}k^{n-1}(-1)^{m-1-k}}{(m-1)!} + sum_{k=0}^{m} cfrac {ino{m}{k}k^{n-1}(-1)^{m-k}}{(m-1)!}\ &=& sum_{k=0}^{m} cfrac {ino{m}{k}k^{n-1}(-1)^{m-k}}{(m-1)!} - sum_{k=0}^{m} cfrac {ino {m-1}{k}k^{n-1}(-1)^{m-k}}{(m-1)!} \ &=& sum_{k=0}^{m} cfrac {ino{m-1}{k-1}k^{n-1}(-1)^{m-k}}{(m-1)!}\ &=& sum_{k=0}^{m} cfrac {(m-1)!k^{n-1}(-1)^{m-k}}{(k-1)!(m-k)!(m-1)!}\ &=& sum_{k=0}^{m} cfrac {m!k^{n}(-1)^{m-k}}{k!(m-k)!m!}\ &=& sum_{k=0}^{m} cfrac {ino mk k^{n}(-1)^{m-k}}{m!}\ &Longrightarrow& m!strb nm = sum_{k=0}^m ino mk k^n (-1)^{m-k}\ end{eqnarray*} $$

      于是自然就可以发现其中的卷积形式。一行斯特林数就可以用 FFT 来快速得到了。

    斯特林反演

      UPD(2019-03-10): 这个东西貌似挺有用的。我更新一下。

      就几个式子:

      先把后面的反转公式抄上来:

    反转公式:

    $$ egin {eqnarray*} sum_{k=1}^n stra nk strb km (-1)^{n-k} &=& [m=n]\ sum_{k=1}^n strb nk stra km (-1)^{n-k} &=& [m=n] end {eqnarray*} $$


      有什么用?

      举个例子:

      假设

    $$g(n) = sum_{i=0}^n strb n i f(i)$$

      则

    $$egin{eqnarray*}f(n) &=& sum_{i=0}^n [i = n] f(i)\ &=& sum_{i=0}^nleft (sum_{k=0}^nstra n kstrb ki(-1)^{n-k} ight)f(i)\&=&sum_{k=0}^n (-1)^{n-k}stra nk sum_{i=0}^n strb k i f(i) \&=& sum_{i=0}^n (-1)^{n-i} stra n i g(i)end{eqnarray*}$$

      类似地,总共可以得到 4 个这样的反演公式:

    $$egin {eqnarray*}f(n) = sum_{i=0}^n strb ni g(i) &Longrightarrow& g(n) = sum_{i=0}^n (-1) ^{n-i }stra ni f(i)\f(n) = sum_{i=0}^n (-1)^{n-i} strb ni g(i) &Longrightarrow & g(n) = sum_{i=0}^n stra ni f(i) \ f(n) = sum_{i=0}^n stra ni g(i) &Longrightarrow & g(n) = sum_{i=0}^n (-1)^{n-i}strb ni f(i)\ f(n) = sum_{i=0}^n (-1)^{n-i}stra ni g(i) &Longrightarrow & g(n) = sum_{i=0}^n strb ni f(i)end{eqnarray*}$$

      可以用于解特定的与斯特林数有关的方程组。

    广义斯特林数

      (我)(只)(知)(道)

    $$ strb nk = stra {-k}{-n} $$

    斯特林数的总结与拓展

    (以下公式来源:具体数学 6.1 节;证明由博主自己瞎证的,仅作参考)

     

    基本式子:

    $$ egin{eqnarray*} strb{n}{k}&=&kstrb{n-1}{k}+strb{n-1}{k-1}\ stra{n}{k}&=&(n-1)stra{n-1}{k}+stra{n-1}{k-1}\ n! &=& sum_{i=0}^{n} stra{n}{i}\ strb nk &=& stra {-k}{-n} end{eqnarray*} $$

     

    特殊值:

    $$ egin{eqnarray*} strb n0 &=& stra n0 = [n=0]\ strb n1 &=& [n>0]\ stra n1 &=& (n-1)![n>0]\ strb n2 &=& (2^{n-1}-1)[n>0]\ stra n2 &=& (n-1)!left (sum_{i=1}^{n-1}frac 1i ight )[n>0]\ strb n {n-1} &=& stra n {n-1} = ino n2\ strb nn &=& stra nn =ino nn = 1\ strb nk &=& stra nk = ino nk = 0 , k > n \ end{eqnarray*} $$

     

    在幂之间转换:

    $$ egin {eqnarray*} x^n &=& sum_{k=0}^{n} strb nk x^udl{k}=sum_{k=1}^n strb nk (-1)^{n-k} x^ovl{k}\ x^udl n &=& sum_{k=0}^{n} stra nk (-1)^{n-k} x^k\ x^ovl n &=& sum_{k=0}^{n} stra nk x^k end {eqnarray*} $$

     

    反转公式:

    $$ egin {eqnarray*} sum_{k=1}^n stra nk strb km (-1)^{n-k} &=& [m=n]\ sum_{k=1}^n strb nk stra km (-1)^{n-k} &=& [m=n] end {eqnarray*} $$

     

    其他斯特林数恒等式:

    $$ egin {eqnarray*} strb{n+1}{m+1}&=&sum_{k=1}^n ino nk strb km \ stra{n+1}{m+1}&=&sum_{k=1}^n stra nk ino km \ strb nm &=& sum_{k=1}^n ino nk strb{k+1}{m+1} (-1)^{n-k}\ stra nm &=& sum_{k=1}^n stra {n+1}{k+1}ino km (-1)^{m-k}\ m!strb nm &=& sum_{k=1}^n ino mk k^n (-1)^{m-k}\ strb {n+1}{m+1} &=& sum_{k=0}^{n} strb km (m+1)^{n-k}\ stra {n+1}{m+1} &=& sum_{k=0}^n stra km n^udl {n-k} = n! sum_{k=0}^n frac{left [ ^{ k }_{ m} ight ]}{k!}\ strb {m+n+1}m &=& sum_{k=0}^m k strb {n+k}k\ stra {m+n+1}m &=& sum_{k=0}^m (n+k) stra {n+k}k\ ino nm &=& sum_{k=1}^n strb {n+1}{k+1}stra km (-1)^{m-k}\ n^udl{n-m}[ngeq m]&=& sum_{k=1}^n stra {n+1}{k+1}strb km (-1)^{m-k}\ strb {n}{n-m} &=& sum_{k=1}^n ino{m-n}{m+k}ino {m+n}{n+k}stra {m+k}{k}\ stra {n}{n-m} &=& sum_{k=1}^n ino{m-n}{m+k}ino {m+n}{n+k}strb {m+k}{k}\ strb {n}{l+m} ino {l+m}{l} &=& sum_{k=1}^n strb kl strb {n-k}m ino nk \ stra {n}{l+m} ino {l+m}{l} &=& sum_{k=1}^n stra kl stra {n-k}m ino nk end {eqnarray*} $$

     

    证明:

    数学归纳及推式子。我比较菜,推的式子都好长。有木有大佬能教教我简单一点的方法?

    (1)

    $$ egin{eqnarray*} strb{n+1}{m+1}&=&sum_{k=1}^n ino nk strb km \ 解:strb{n+1}{m+1}&=&(m+1)strb{n}{m+1}+strb nm \ &=&strb nm + (m+1) sum_{k=1}^{n-1}ino{n-1}k strb km \ &=&strb nm + sum_{k=1}^{n-1}ino {n-1}k strb km + m sum_{k=1}^{n-1}ino{n-1}k strb km \ &=&strb nm + sum_{k=1}^{n-1}ino nk strb km - sum_{k=1}^{n-1} ino {n-1}{k-1} strb km + m sum_{k=1}^{n-1}ino{n-1}k strb km \ &=&sum_{k=1}^{n}ino nk strb km - sum_{k=1}^{n-1}ino {n-1}{k-1} left ( strb{k-1}{m-1}+m strb {k-1}m ight ) + cdots \ &=&cdots -sum_{k=0}^{n-2}ino {n-1}k left ( strb k{m-1}+mstrb km ight ) + msum_{k=0}^{n-1}ino {n-1}k strb km \ &=&cdots + mstrb{n-1}m - sum_{k=0}^{n-2}ino{n-1}k strb k{m-1} \ &=&cdots +strb nm - strb {n-1}{m-1} - sum_{k=0}^{n-2}ino{n-1}k strb k{m-1} \ &=&cdots +strb nm - sum_{k=0}^{n-1}ino{n-1}k strb k{m-1} \ &=&cdots + 0 = sum_{k=1}^n ino nk strb km end{eqnarray*} $$

     

    (2)

    $$ egin{eqnarray*} stra{n+1}{m+1}&=&sum_{k=1}^{n} stra nk ino km \ 解:stra{n+1}{m+1}&=&stra nm + n stra n{m+1}\ &=&stra nm + sum_{k=1}^{n-1} nstra {n-1}k ino km \ ecause (n-1)stra{n-1}k&=&stra nk - stra {n-1}{k-1}\ herefore 原式 &=&stra nm + sum_{k=1}^{n-1}left ( stra nk -stra {n-1}{k-1}+stra {n-1}k ight )ino km\ &=& stra nm - ino nm + sum_{k=1}^{n} stra nk ino km + sum_{k=1}^{n-1}left ( stra {n-1}k - stra {n-1}{k-1} ight )ino km\ &=& cdots + sum_{k=1}^{n-1}left ( stra {n-1}k - stra {n-1}{k-1} ight )ino km\ &=& cdots + ino {n-1}m - sum_{k=1}^{n-2} stra {n-1}k left ( ino {k-1}m - ino km ight )\ &=& cdots + ino {n-1}m - sum_{k=1}^{n-2} stra {n-1}k ino k{m-1}\ &=& cdots + ino {n-1}m + ino {n-1}{m-1} - sum_{k=1}^{n-1} stra {n-1}k ino k{m-1}\ &=& cdots + ino nm - stra nm \ &=& sum_{k=1}^n stra nk ino km end{eqnarray*} $$

     

    (3)

    $$ egin{eqnarray*} strb nm &=& sum_{k=1}^{n} ino nk strb{k+1}{m+1} (-1)^{n-k}\ 解:strb nm &=& strb{n+1}{m+1} - (m+1) strb n {m+1} \ &=&sum_{k=1}^{n+1}ino {n+1}k strb{k+1}{m+2}(-1)^{n-k+1} - (m+1) sum_{k=1}^n ino nk strb {k+1}{m+2}(-1)^{n-k}\ &=&sum_{k=1}^n left ( ino {n+1}k - ino nk ight ) strb {k+1}{m+2} (-1)^{n-k+1}+strb{n+2}{m+2} \&& -(m+2)sum_{k=1}^n ino nk strb {k+1}{m+2}(-1)^{n-k}\ &=&sum_{k=1}^n ino n {k-1}strb {k+1}{m+2}(-1)^{n-k+1}+strb{n+2}{m+2}-(m+2) imes cdots \ &=&sum_{k=0}^n ino nk strb{k+2}{m+2}(-1)^{n-k} - (m+2) sum_{k=1}^n ino nk strb {k+1}{m+2}(-1)^{n-k} \ &=&sum_{k=1}^n ino nk strb{k+2}{m+2}(-1)^{n-k} - (m+2) sum_{k=1}^n ino nk strb {k+1}{m+2}(-1)^{n-k} \ &=&sum_{k=1}^n ino nk left ( strb {k+2}{m+2}-(m+2)strb{k+1}{m+2} ight )(-1)^{n-k}\ &=&sum_{k=1}^n ino nk strb {k+1}{m+1} (-1)^{n-k}\ &&然后您仔细一看发现我的这个数学归纳是假的????\ &&没错,是假的,因为这样归纳下去就没有终点了。但是,这个推导可以表明一点:\ &&在证明第一行的三个斯特林数中,如果两个满足了要求证明的性质,那么第三个也满足。\ &&这说明我们只需要用 strb {n}{m} 和 strb n{m+1} 来归纳证明strb{n+1}{m+1}就可以了。\ &&具体来说,就是移个项。 end{eqnarray*} $$

      剩下的式子就留(gu)给(gu)读(gu)者了。 

    鸣谢

      感谢《具体数学》。

      陈老爷太强了。已经秒掉了此博文的所有内容。

  • 相关阅读:
    Linux基础命令—clear
    Linux基础命令—mv
    Linux基础命令—rm
    Linux基础命令—cp
    Linux基础命令—touch
    Linux基础命令—tree
    C#获取设备话筒主峰值(实时音频输出分贝量)
    C# 获取基类或者接口的所有继承类方法
    RegisterAttached 两种绑定方式
    RijndaelManaged 加密
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/Stirling-Number.html
Copyright © 2011-2022 走看看