1. 程式人生 > 其它 >指數生成函式學習筆記&做題記錄

指數生成函式學習筆記&做題記錄

咕咕了好久,指數生成函式 (EGF) 它終於來了!

前置知識

普通生成函式

多項式計數


一些定義

指數生成函式 (EGF) 指下面這種形式的生成函式:

\[\hat A(x)=\sum_{i \ge 0} \frac{a_i}{i!}x^i \]

卷積形式:

\[\hat A(x)\hat B(x)=\sum_{i\ge 0} \frac{x^i}{i!}\sum_{j=0}^i \binom{i}{j}a_jb_{i-j} \]

這個直接把 \(i!\) 移動到後面去就好了。

有啥用

指數生成函式主要解決有標號的圖的計數問題。

在解決這個之前,我們先要解決它的封閉形式。

對於 \(a_i=1\)

,來說,它的生成函式就是:

\[\hat A(x)=\sum_{i\ge 0}\frac{x^i}{i!}=e^x \]

這個可以使用泰勒展開證明。

同理,對於 \(a_i=p^i\) 形式,那麼同理, \(\hat A(x)=e^{px}\)

會求這個東西之後,可以來解決有標號圖計數問題。

具體作用就是,EGF 可以實現一般圖連通圖直接的轉化。

假設 \(n\) 個點的一般圖的 EGF 是 \(\hat F\),連通圖是 \(\hat G\)

那麼結論是:

\[\hat F=e^{\hat G}\\ \hat G=\ln \hat F \]

這兩個直接做都是 \(O(n\log n)\)

考慮證明它,對第一個進行證明,考慮對於一個一般圖,列舉一下連通塊個數。

\[f_n=\sum_{i\ge 0}\frac{1}{i!}\sum_{a_1+a_2+...a_i=n}\binom{n}{a_1,a_2...,a_i}\prod_{j=1}^i g_{a_j} \]

後面的好理解,考慮前面的 \(\frac{1}{i!}\) 是啥。

考慮把每個點放到 \(i\) 個集合中的一個,那麼每個數可以隨便選,但是對於一種選法,可以把集合的編號進行隨意排列,這樣得到的計數結果會重複,所以除掉這樣的 \(i!\)

然後直接化簡:

\[\frac{f_n}{n!}=\sum_{i\ge 0}\frac{1}{i!}\sum_{a_1+a_2+...a_i=n}\prod_{j=1}^i \frac{g_{a_j}}{(a_j)!}\\ \hat F_n=\sum_{i\ge 0}\frac{1}{i!}\sum_{a_1+a_2+...a_i=n}\prod_{j=1}^i \hat G_{a_j}\\ =[x^n] \sum_{i\ge 0}\frac{(\hat G)^i}{i!} \\ \hat F=e^{\hat G} \]

下面是有標號計數大雜燴。


  • 有標號無根樹、森林計數。

樹直接 purfer 序列,答案是 \(n^{n-2}\),森林的話就直接求 \(\exp\) 即可。


  • 有標號有根樹、森林計數。

樹直接 purfer 然後去定一個根,\(n^{n-1}\),森林有一個更優美的做法,把所有根連向 \(0\),然後就可以直接 purfer 了,答案是 \((n+1)^{n-1}\)


  • 有標號無向圖計數。P4841

不連通直接

\[f_n=2^{\frac{n(n-1)}{2}} \]

然後轉 EGF,求 \(\ln\) 即可。

code


  • 有標號 DAG 計數。P6295

考慮不連通咋做,是 bzoj2863

考慮一張 DAG 中,如果把所有入度為 \(0\) 的點扔掉,那麼必然還是一個 DAG,所以可以列舉有幾個點入度為 \(0\),然後會發現這個東西需要容斥,式子就是:

\[f_n=\sum_{i=1}^n (-1)^{i-1} 2^{i(n-i)}\binom{n}{i}f_{n-i} \]

暴力做複雜度 \(O(n^2)\),可以過上面的題。

考慮化簡。

\[\frac{f_n}{n!}=\sum_{i=1}^n \frac{(-1)^{i-1}}{i!}\frac{f_{n-i}}{(n-i)!}2^{i(n-i)} \]

此時有一個問題就是說 \(2^{i(n-i)}\) 做不了。

考慮把它變成可以用 \(i,n-i,n\) 表示的東西。

可以發現 \(2^{ab}=2^{\frac{(a+b)^2-a^2-b^2}{2}}\),這樣就可以了。

但有一個問題,就是除二不一定可以整除,會寄,可以把 \(2\) 變成 \(\sqrt{2}\) 然後求二次剩餘,但是太麻煩了。

考慮換一下:\(2^{ab}=2^{\frac{(a+b)(a+b+1)-a(a+1)-b(b+1)}{2}}\),此時就可以拆了。

拿去原式,變成:

\[\frac{f_n}{n!2^\frac{n(n+1)}{2}}=\sum_{i=1}^n \frac{(-1)^{i-1}}{i!2^\frac{i(i+1)}{2}}\frac{f_{n-i}}{(n-i)!2^{\frac{(n-i)(n-i+1)}{2}}} \]

此時有一個尋寶做法,直接分治 NTT 求,時間複雜度 \(O(n\log^2 n)\)

AK 做法是,直接換成 \(F=GF+1\) 的形式,直接多項式求逆,時間複雜度 \(O(n\log n)\)

連通的話直接求 \(\ln\) 即可。

code