集合冪級數的ln和exp運算及組合意義


集合冪級數的ln和exp運算及組合意義

子集卷積

\(f,g,h\)為集合冪級數
定義\(h\)\(f\)\(g\)的子集卷積

\[h_S=\sum_{L}\sum_{R} f_L g_R [L \cap R=\emptyset][L \cup R=S] \]

注意到\([L \cap R=\emptyset][L \cup R=S]=[|L|+|R|=|S|][L \cup R=S]\)

我們定義集合占位冪級數 \(F_{i,S}\),\(F_{|S|,S}=f_S\),其余情況為0

那么上面的式子就可以簡化為

\[H_{k,S}=\sum_i\sum_j\sum_L\sum_R[i+j=k][L \cup R=S]F_{i,L} G_{j,R} \]

容易發現,第一維是一個普通卷積,而第二維是集合冪級數的or卷積. 而集合占位冪級數可以看成一個二元生成函數,每一維之間是獨立的,只需要分開即可.(可以考慮多項式的乘法如\((xy+x^2y)(2x^2y+3y^2)\),感性理解即可)

那么我們處理這個卷積時,只需要對每一行\(f_i\)做FMT,然后對於每一列,暴力做普通卷積,再把每一行IFMT回來即可。因為有\(n\)\(2^n\)列,所以復雜度\(O(n^22^n)\)

集合冪級數exp

我們考慮EGF的組合意義,EGF的exp表示把元素組合成集合的方案數。不妨定義\(F_{|S|,S}=\frac{f_S}{|S|!}\). 那么每一列就是一個EGF. 我們先定義占位集合冪級數的exp為\(\exp F -1=\sum_{i\geq 1}\frac{F^i}{i!}\),其中\(F\)的乘法定義為子集卷積. 由於占位集合冪級數中中兩維的獨立性,這等價於對第一維做普通卷積意義下的exp,對第二維做or卷積.

實現時,類似子集卷積,先對行FMT,再列exp,再IFMT回來即可. 對列做exp,當然可以用多項式全家桶做到\(O(n\log n)\),但常數爆炸。因為\(n\)很小,考慮如何\(O(n^2)\)做exp.

\(G=\exp F -1\)

兩邊求導得\(G'=F' \exp F=F'G\)

寫成系數形式\(ng_n=\sum_{i=0}^{n-1}if_ig_{n-i}\),即

\[g_n=\frac{1}{n} \sum_{i=0}^{n-1}if_ig_{n-i}\]

集合冪級數的exp好像十分抽象,我們現在探討它的組合意義. 設\(g_n\)為真實的方案數(沒有除掉EGF中的n!)

\[\frac{g_n}{n!}=\sum_{i=0}^{n-1} \frac{i}{n} \frac{f_i}{i!} \frac{g_{n-i}}{(n-i)!} \]

\[g_n=\sum_{i=0}^{n-1} \frac{i}{n}\binom{n}{i}f_i g_{n-i}=\sum_{i=0}^{n-1} \binom{n-1}{i-1}f_i g_{n-i} \]

組合解釋如下: 枚舉\(n\)所在的集合的大小\(i\),那么該集合內部的方案數為\(f_i\).從的\(n-1\)個數中選\(i-1\)個數與\(n\)放到同一集合。剩下的\(n-i\)個數隨便放,方案數\(g_{n-i}\). 那么exp的意義就是選取若干個不相交的集合組合成S的方案數

void exp(int *f,int *g,int n){
	static int F[maxlogn+5][maxn+5],G[maxlogn+5][maxn+5];
	for(int i=0;i<(1<<n);i++) for(int j=0;j<=n;j++) F[j][i]=G[j][i]=0;
	for(int i=0;i<(1<<n);i++) F[cnt[i]][i]=f[i];
	for(int i=0;i<=n;i++) FMT(F[i],n,1);
	G[0][0]=1;
	FMT(G[0],n,1);
	for(int s=0;s<(1<<n);s++){
		for(int i=1;i<=n;i++){
			for(int j=0;j<=i-1;j++) G[i][s]=addm(G[i][s],1ll*F[j][s]*j*G[i-j][s]%mod);
			G[i][s]=1ll*G[i][s]*invi[i]%mod;
		}
	} 
	for(int i=0;i<=n;i++) FMT(G[i],n,-1);
	for(int i=0;i<(1<<n);i++) g[i]=G[cnt[i]][i];
}

定義\(G\)的生成子圖為包含\(G\)的所有頂點的子圖。給出一個圖G,求G的連通生成子圖數量

集合冪級數ln

之前我們定義了\(e^G-1=F\).同理,我們定義\(G=\ln(F+1)\)

同樣,對第一維做普通卷積意義下的ln,對第二維做or卷積.考慮如何\(O(n^2)\)ln.

我們只需要把exp的式子反過來就好了

\[g_n=\frac{1}{n} \sum_{i=0}^{n-1}if_ig_{n-i}\]

\[f_n=g_n-\frac{1}{n}\sum_{i=1}^{n-1}if_ig_{n-i} \]

再把字母換一下就得到了

\[g_n=f_n-\frac{1}{n}\sum_{i=1}^{n-1}ig_if_{n-i} \]

由exp的組合意義可知,ln的組合意義為將S拆分成若干個不相交集合的方案數

void ln(int *f,int *g,int n){
	static int F[maxlogn+5][maxn+5],G[maxlogn+5][maxn+5];
	for(int i=0;i<(1<<n);i++) for(int j=0;j<=n;j++) F[j][i]=G[j][i]=0;
	for(int i=0;i<(1<<n);i++) F[cnt[i]][i]=f[i];
	for(int i=0;i<=n;i++) FMT(F[i],n,1);
	G[0][0]=1;
	FMT(G[0],n,1);
	for(int s=0;s<(1<<n);s++){
		for(int i=1;i<=n;i++){
			for(int j=0;j<=i-1;j++) G[i][s]=addm(G[i][s],1ll*F[i-j][s]*G[j][s]%mod*j%mod);
			G[i][s]=decm(F[i][s],1ll*G[i][s]*invi[i]%mod)%mod;
		}
	} 
	for(int i=0;i<=n;i++) FMT(G[i],n,-1);
	for(int i=0;i<(1<<n);i++) g[i]=G[cnt[i]][i];
}

k-exp

我們在ln和exp的定義中,都沒有限制拆分成集合的個數,如\(\sum_{i \geq 1}\frac{F^i}{i!}\),i的取值是1到n. 如果限制拆分的個數之多為k,我們就得到了k-exp

\(G=\sum_{i=1}^k \frac{F^i}{i!}\)

同樣兩邊求導,有\(G'=F'(G-\frac{F^k}{k!})\),因為對右邊求導后,每一項都變成了前一項,只有第k項消失了

同樣考慮每一列怎么做.對\(F^k\)做多項式快速冪(即先ln,乘k再exp),設得到的結果為\(h\).那么上式就可以寫成

\(ng_n=\sum_{i=0}^{n-1}(n-i)f_{n-i}(g_i-h_i)\)

就可以在\(O(n^2)\)的時間內求解

模板題LOJ 154
代碼

彩蛋


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM