LuoguP5748 集合劃分計數

2021-10-02 13:01:39 字數 1295 閱讀 8277

乙個有\(n\)個元素的集合,將其分為任意個非空子集,求方案數。集合之間是無序的,\(\,\\}=\,\\}\)。

設\(f_n\)表示用\(n\)個元素組成的集合的個數,顯然\(f_n=1\)。設\(f(x)\)為\(f\)的指數型生成函式,那麼\(f(x)=\sum_\frac\),\(f^i(x)\)的第\(n\)位就是\(i\)個元素個數之和為\(n\)的集合組合在一起的方案數。

設\(g_i\)為\(n=i\)時的答案,再設\(g(x)\)為\(g\)的指數型生成函式。列舉劃分的集合個數:

\[ g(x)=\sum_\frac \]

顯然\(f(x)=e^x-1\),那麼\(g(x)=e^\),\(g(x)\)第\(i\)項乘\(i!\)就是\(g_i\)。多項式\(exp\)即可。

#include#define rg register

#define il inline

#define cn const

#define gc getchar()

#define fp(i,a,b) for(rg int i=(a),ed=(b);i<=ed;++i)

#define fb(i,a,b) for(rg int i=(a),ed=(b);i>=ed;--i)

using namespace std;

typedef cn int cint;

il int rd()

il int finv(cint &n)

cint g=3,invg=finv(g);

il void ntt(int *a,cint &f)

il void get_ln(int *a,int *b,int n)

void get_exp(int *a,int *f,int n)

get_exp(a,f,n>>1),get_ln(f,g,n);

g[0]=(1-g[0]+a[0]+mod)%mod; fp(i,1,n)g[i]=(a[i]-g[i]+mod)%mod;

lim=1,l=0; while(lim<=n<<1)lim<<=1,++l; rev=finv(lim);

fp(i,0,lim-1)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));

ntt(f,1),ntt(g,1);

fp(i,0,lim)f[i]=1ll*f[i]*g[i]%mod; ntt(f,0);

fp(i,0,n)f[i]=1ll*f[i]*rev%mod; fp(i,n+1,lim)f[i]=0;

fp(i,0,lim)g[i]=0;

}int main()

洛谷 P5748 集合劃分計數 題解

題目傳送門 題目大意 多次詢問,求貝爾數的第 n nn 項。先考慮只有乙個集合的情況,設 f if i fi 表示 i ii 個不同元素分成 1 11 個集合的方案數,顯然有 fi 1f i 1 fi 1,由於不允許有空集,所以 f0 0f 0 0 f0 0。設 f ff 的 egf egfeg f...

2 7 集合劃分問題

問題描述 n 個元素的集合可以劃分為若干個非空子集。例如,當 n 4 時,集合可以劃分為 15 個不同的非空子集如下 程式設計任務 給定正整數 n,計算出 n 個元素的集合可以劃分為多少個不同的非空子集。資料輸入 由檔案 input.txt 提供輸入資料。檔案的第 1 行是元素個數 n。結果輸出 程...

luogu P2415 集合求和

今天下午沒什麼精神,於是跑去刷水題,刷什麼水題才不會太水呢?肯定是數論題了,然後就有了這道題。給定乙個集合,求它所有子集的元素和。各位大神推導的結論是每乙個元素一定會出現2 n 1次,然後我這個蒟蒻就又採用了一種辣雞做法。我們知道乙個n個元素的集合,m個元素的子集有c n,m 個,而在這些集合的總體...