第二類斯特林數 學習總結

2022-05-31 06:24:06 字數 4508 閱讀 7187

前幾天在bz上的考試考到有關第二類斯特林數的東西

雖然說那道題目到最後並不需要用這個東西來化簡把

不過抱著學習的態度還是學了學有關第二類斯特林數的東西

第二類斯特林數s(n,m)定義為把n個元素劃分成m個無序集合的方案數

根據這個定義我們不難寫出遞推式

設狀態s(i,j),討論第i個元素是否單獨乙個集合

若單獨乙個集合,則方案數等價於s(i-1,j-1)

若不是單獨乙個集合,則他可以在之前任意j個集合裡,方案為s(i-1,j)*j

這樣我們得到式子s(i,j)=s(i-1,j-1)+s(i-1,j)*j

遞推的時間複雜度是o(n^2)的

根據定義我們也不難寫出通項表示式

假設集合沒有非空的限制,則答案顯然是m^n

之後我們可以利用容斥原理,列舉至少有幾個集合是空的,在套上容斥係數我們有(注意集合是無序的,所以最後要消序)

s(n,m)=1/m!*sigma((-1)^k*c(m,k)*(m-k)^n))

直接根據這個式子暴力求解某一行的斯特林數的複雜度是o(n^2)的

但顯然這是乙個卷積形式,利用fft我們可以將時間複雜度優化成o(nlogn)

我們再來討論一下貝爾數,貝爾數的定義是把n個元素劃分成若干個無序集合的方案數

不難發現f(n)=sigma(s(n,m)),直接求解某一項貝爾數利用上面的通項公式我們可以做到o(nlogn)

但是我們可以做到更好,考慮第乙個元素所在集合的大小,我們不難得到如下遞推式

f(i)=sigma(c(i-1,k-1)*f(i-k))

我們對於這個式子利用cdq+fft即可在o(nlog^2n)的時間複雜度內求解前n項的貝爾數

但是我們還可以做到更好

我們考慮每個集合是由若干個元素組成的且集合非空,集合中元素無序

則可以得到集合的生成函式為g(x)=e^x-1

而貝爾數分解成若干個集合的劃分方案,則我們有f=e^g

我們構造多項式g,之後多項式求exp即可

時間複雜度o(nlogn)

有意思的是我們可以考慮把n個元素劃分成若干個有序集合的方案數,設為多項式f

考慮第乙個集合的大小,我們有

f(i)=sigma(c(i,k)*f(i-k))

我們一樣可以用cdq+fft來求解

但是我們利用之前在多項式求逆學習總結中提過的技巧進行化簡,就可以化簡成乙個多項式求逆的式子

時間複雜度o(nlogn)

我們現在討論一些跟斯特林數相關的化簡技巧

其中最常用的莫過於i^k和s(k,j)之間的轉化了

我們通過第二類斯特林數的通項公式不難發現s(k,j)可以轉化成若干個帶係數的i^k的和

而我們又存在公式i^k=sigma(s(k,j)*j!*c(i,j))

不難發現這裡跟i有關的項其實只有c(i,j),我們就把冪通過第二類斯特林數轉化成了組合數

更有趣的是,這個式子後面j!*c(i,j)實際上暴力計算的時間複雜度是o(j)的 qaq

即計算i的下降階乘冪

我們來看幾道題目qaq

bz的題目由於某些奇怪的原因貌似不能放出來qaq

首先是crash的文明世界 cojs 1888

這是道很有趣的題目,首先我們如果對(i+1)^k暴力用二項式定理展開會得到乙個時間複雜度為o(n*k^2)的dp方程

注意到這裡狀態是o(n*k)的,而轉移是o(k)的

由於k很小,我們考慮運用第二類斯特林數將i^k轉化為c(i,j)

由於c(i,j)=c(i-1,j)+c(i-1,j-1),我們利用這個式子可以做到轉移o(1),這樣時間複雜度就是o(n*k)的

具體做法是設f(i,j)表示第i個點的c(dis(i,o),j)的和

然後從底向上做一遍dp,然後從上向下在做一遍dp

求出第二類斯特林數還原答案即可

#include#include#include#include#includeusing namespace std;

typedef long long ll;

const int maxn=50010;

const int mod=10007;

int n,k,l,u,v;

int now,a,b,q;

int h[maxn],cnt=0;

struct edgeg[maxn<<1];

int f[maxn][151];

int jc[151],inv[151];

int s[151][151];

void add(int x,int y)

void get_read()return tmp;

}void get_s()

jc[0]=1;

for(int i=1;i<=k;++i)jc[i]=jc[i-1]*i%mod;

inv[k]=pow_mod(jc[k],mod-2);

for(int i=k-1;i>=0;--i)inv[i]=inv[i+1]*(i+1)%mod;

}void get_dfs(int u,int fa)return;

}void get_dp(int u,int fa)

f[v][1]=(f[u][0]+f[u][1]-2*f[v][0])%mod;

if(f[v][1]<0)f[v][1]+=mod;

f[v][0]=f[u][0];

get_dp(v,u);

}return;

}int main()printf("%d\n",ans);

}return 0;

}

cojs 2359 qaq的圖論題

qaq 題解在blog裡,寫的非常詳細 qaq

具體做法是考慮每個點的貢獻寫出o(n)的計算式,之後把i^k用第二類斯特林數表示

化簡之後計算的時間複雜度變成o(k),然後利用fft在o(klogk)的時間內求出我們所需要的斯特林數就可以了

#include#include#include#include#include#define g 3

using namespace std;

typedef long long ll;

const int mod=998244353;

const int maxn=300010;

int n,k,n,len,ans,now;

int jc[maxn],inv[maxn],rev[maxn];

int a[maxn],b[maxn],w[maxn];

int pow_mod(int v,int p)return tmp;

}void fft(int *a,int n,int flag)

for(int i=0;i<=k;++i)b[i]=1ll*pow_mod(i,k)*inv[i]%mod;

for(n=1,len=0;n<=k;n<<=1,len++);n<<=1,len++;

for(int i=0;i>1]>>1|((i&1)<<(len-1));

fft(a,n,1);fft(b,n,1);

for(int i=0;icojs 2272 heoi2016 sum

qaq 考試的時候沒有做出來,所以要反反覆覆的多虐幾遍 qaq

第一發的做法是cdq+fft,第二發的做法是多項式求逆

而現在會了第二類斯特林數的一些性質,我們有了第三種做法

前兩種做法都是設f(i)=sigma(s(i,j)*2^j*j!)

但是我們不妨轉換思路,設f(i)=sigma(s(j,i))

這樣我們求完之後對每一項乘以2^i*i!就可以了

考慮把s(j,i)用通項公式展開

對於s(n,m)我們有s(n,m)=sigma((-1)^k*c(m,k)*(m-k)^n)

不難發現跟n有關的項只有(m-k)^n,提出來求sigma可以用等比數列求和公式化簡掉

之後帶入原式我們發現這是乙個裸的卷積形式,直接做fft就可以了

#include#include#include#include#include#define g 3

using namespace std;

typedef long long ll;

const int maxn=300010;

const int mod=998244353;

int n,n,len,ans,now;

int jc[maxn],inv[maxn];

int a[maxn],b[maxn],rev[maxn];

int w[maxn];

int pow_mod(int v,int p)return tmp;

}void fft(int *a,int n,int flag)b[1]=n;

for(int i=2;i<=n;++i)

for(n=1,len=0;n<=n;n<<=1,len++);n<<=1,len++;

for(int i=0;i>1]>>1|((i&1)<<(len-1));

fft(a,n,1);fft(b,n,1);

for(int i=0;iqaq 第二類斯特林數還是很有趣的呢

準備在cojs補上一道求貝爾數的題目qaq

第二類斯特林數總結

標籤 第二類斯特林數 最近做題的時候遇到了一些跟第二類斯特林數有關的東西,發現網上的資料不是很多,於是寫一篇部落格來總結一下。第二類斯特林數 s n,m 表示的是把n個不同的小球放在m個相同的盒子裡方案數。upd 為了看得清楚,有時候我們也用 begin n m end 來表示 s n,m 一般有兩...

學習筆記 第二類斯特林數

在組合數學中,有幾個重要的 遞推數 而筆者今天要介紹的,就是其中的第二類斯特林數。第二類斯特林數 即斯特林子集數 beginn k end 也記作 s n,k 它表示將 n 個兩兩不同的元素,劃分為 k 個互不區分的非空子集的方案數。每次加入乙個新元素時,有兩種方案 根據加法原理,即可得出遞推式 b...

模板 第二類斯特林數 列

從通項公式入手好像不行了。法一 直接從定義入手 把n個球劃分成m個等價類 假設等價類兩兩不同,最後除以m!直接上egf,a 1 i x i a m的i次項係數,再乘上i!再除以m!法二 從遞推公式入手 s n,m s n 1,m 1 m s n 1,m 設ogf s m x 是第m列二斯的ogf,則...