概念
- 斯特林數(Stirling number)是由18世紀數學家James Stirling提出的兩類數。
- 第一類:輪換數,將n個數排成k個非空的環(圓排列,有序)的方案數,用s(n,m)或[nk]表示。還分爲無符號第一類斯特林數su(n,m)和帶符號第一類斯特林數 ss(n,m)。
- 第二類:子集數,將n個數排成k個非空集合(集合內無序)的方案數,用S(n,m)或{nk}表示。
第一類斯特林數
邊界條件&&遞推式
- 先考慮無符號第一類斯特林數su(n,m)。
- 根據定義,易得邊界條件:
s(n,k)=⎩⎪⎨⎪⎧010n<kn=kn>0 ∧ k=0
- 假設現在已知s(n−1,k−1),我們要加入一個新數n。它可以考慮自己形成一個新的環,或者插入任意一個已有的數後面,因此:[nk]=[n−1k−1]+(n−1)[n−1k]
- 有符號的第一類斯特林數ss(n,k)與此類似。其遞推式爲:ss(n,k)=(−1)n+ksu(n,k)=ss(n−1,k−1)−(n−1)×ss(n−1,k)
- 時間&空間複雜度:O(n2)。
與上升/下降冪的關係
- 第一類斯特林數與上升冪xn=x(x+1)(x+2)⋯(x+n−1)滿足如下所示的關係:
xn=k=1∑nsu(n,k)×xk
- 亦即第一類斯特林數表現爲xn的展開形式的各項係數。
- 該式子可利用su(n,m)的遞推式通過數學歸納法來證明。但其亦有簡單的組合意義:
- n個點,構成若干個環,要求一個環中所有點顏色相同,不同環不作要求。那麼我們可以枚舉環的組成(∑k=1nsu(n,k)),再給每個環分配顏色(xk);從另一個角度想,我們按編號從小到大加入每個點,每個點可在x種顏色中選擇一種並自己形成一個新的環,亦可在前n−1個點中選擇一個點接在它後面並繼承它的顏色,那麼操作方案數即爲xn。
- 上式加以變形可得到與下降冪xn=x(x−1)(x−2)⋯(x−n+1)的關係:
xn=k=1∑n(−1)n−k×su(n,k)×xk=k=1∑nss(n,k)×xk
- 這是因爲我們把xn展開後,會發現它的各項係數的絕對值與xn一致,只是正負性會交錯排列。
較爲快速的求法
- 考慮多項式F(x)=∏i=0n−1(x+i)的係數。
- F(x)=xn=∑k=1n[kn]xk=∑k=0n[kn]xk
- 因此,F(x)的k次項係數即爲[kn]。
- 考慮快速地求解[kn]。
- 當有模數的時候,可以分治NTT求解F(x)的各項係數(可以忽略掉i=0時的(x+i))。我們進行CDQ分治,區間[2l−1,2r]表示(x+l)(x+l+1)(x+l+2)⋯(x+r)的各項係數。記m=2l+r,每次先求解區間[2l−1,2m]和區間[2m+1,2r],爾後再合併。
- 時間複雜度:O(nlog22n);空間複雜度:O(n)。
第二類斯特林數
回顧一下定義
- 第二類斯特林數:子集數,將n個數排成k個非空集合(集合內無序)的方案數,用S(n,m)或{nk}表示。
邊界條件&&遞推式
- 隨便思考一下即可發現,邊界條件與第一類斯特林數一致:
S(n,k)=⎩⎪⎨⎪⎧010n<kn=kn>0 ∧ k=0
- 假設現在已知S(n−1,k−1),要加入新數n。它可以自己形成一個新的集合,或者加進先前已有的任意一個集合中去,於是:{nk}={n−1k−1}+k{n−1k}
- 時間&空間複雜度:O(n2)。
與下降冪的關係
- 第二類斯特林數與下降冪xk滿足如下所示的關係:
xn=k=0∑nS(n,k)×xk
- 與前面的一樣,這個式子可以用數學歸納法證明,亦有組合意義:
- 假設我們用x種顏色爲n個點染色,方案數顯然是xn;而我們也可以枚舉同種顏色的集合是什麼(∑k=0nS(n,k)),然後從x種顏色中選出不同的顏色賦給這些集合(xk)。
通項公式
- 轉換模型。不難發現S(n,k)等價於:將n個不同的球放入m個無差別的盒子中,要求盒子非空的方案數。
- 我們先考慮盒子有差別的情況。
- 考慮容斥。枚舉空盒數i,在m個盒子中選i個即爲(im);那麼,n個球可以放進剩下的m−i個盒子中,即爲(m−i)n。容斥係數顯然爲(−1)i。(當然,嚴謹證明還是得推式子)
- 最後,消除盒子的差別,整體乘上一個m!1。
- 以上說明過於感性,下面我們來理性一下。
- 我們之前已經得出了:mn=∑i=0n{in}mi
- 把mi拆開來就變成:∑i=0n(kn){kn}x!
- 那麼,根據二項式反演,上式等價於:{mn}m!=∑i=0m(−1)i(im)(m−i)n
- 然後,我們把m!丟到右邊去。
- 至此,我們得到了第二類斯特林數的通項公式:
{nm}=m!1i=0∑m(−1)i(im)(m−i)n=i=0∑mi!(m−i)!(−1)i(m−i)n
- 可以考慮預處理i!(m−i)!1。單組詢問的話,也可以預處理(m−i)n。
- 時間複雜度:O(mlogM)或O(m)。(M爲模數)
- 如果我們要快速地求S(n,0)∼S(n,m)怎麼破?我們發現通項公式中,i!(−1)i只與i有關,(m−i)!(m−i)n只與m−i有關。所以可設兩個多項式,用一個FFT/NTT,即可在O(mlogm)的時間內求出。
與自然數冪和
- 第二類斯特林數的一大亮點是可以
龜快速求自然數冪和。
- 記F(n)=∑i=1nik。我們來現場推一波式子:
F(n)=i=1∑nj=0∑k{kj}ij=i=1∑nj=0∑k{kj}j!(ij)=j=0∑k{kj}j!i=j∑n(ij)
- 現在已經可以O(nk)求解了。但是我們想更快。
- 先給出一個結論:∑i=jn(ji)=(j+1n+1)。
- 這個東西的證明,可以根據組合數的遞推式依次展開(j+1n+1)來得到:
(n+1j+1)=(nj)+(nj+1)=(nj)+(n−1j)+(n−1j+1)=(nj)+(n−1j)+(n−2j)+(n−2j+1)=(nj)+(n−1j)+⋯+(jj)+(jj+1)=(nj)+(n−1j)+⋯+(jj)
- 也可以考慮組合意義:n+1個數排成一排,選j+1個,枚舉第一個數選的位置,剩下的數再選j個,於是就成了上面的式子。
- 然後我們可以繼續化簡。
- 接着上面的隊形:
F(n)=j=0∑k{kj}j!i=j∑n(ij)=j=0∑k{kj}j!(n+1j+1)=j=0∑k{kj}j+1(n+1)j+1
- {jk}的值可以O(k2)或O(klogk)預處理。而(n+1)j+1是連續的j+1個自然數的乘積,則其一定是j+1的倍數,因此不必逆元。(當然,假如(n+1)太大,要先模,那就得逆元了)逆元可以O(k)預處理,因此單次詢問複雜度爲O(k)。
兩類斯特林數之間的關係
i=0∑nS(n,i)s(i,m)=i=0∑ns(n,i)S(i,m)
- 這是爲什麼呢?我覺得應該可以數學歸納法,在此不作證明。