zoukankan      html  css  js  c++  java
  • 指数生成函数(EGF)计数小记

    有标号无向连通图计数

    首先设 (f_i) 表示 (i) 个点的有标号连通图个数,(g_i) 表示 (i) 个点的任意图个数,很显然 (g_i = 2^{ichoose2})

    (langle f_1,f_2, cdots,f_n,cdots angle) 的指数生成函数(EGF)为 (F(x))(langle g_1,g_2, cdots,g_n ,cdots angle) 的指数生成函数为 (G(x))。考虑 (F,G) 之间的关系:很显然一般图是由若干个连通图拼接而成。那么枚举连通块个数,得下式:

    [G(x)=sum_{ige 1} dfrac{F^i(x)}{i!} ]

    可以发现这是 (exp) 的一个定义,于是:

    [G(x) = exp F(x) Leftrightarrow F(x) = ln G(x) ]

    实际上,在有标号计数中,(exp) 往往可以表示若干个组的组合,而 (ln) 则是其反演。

    接下来有一个更严谨的正确性证明:

    枚举组数 (k),由于带标号所有组与组之间必然不同。如果是利用卷积就行组合那么默认是有先后顺序的,实则不然。不过这可以简单地 (/k!) 来去重。

    考虑大小为 (n),分为大小为 (a_1, a_2, cdots , a_k) 大小的组。首先需要分配标号,从 (n) 个标号分出 (k) 组来,那么就是:

    [dfrac{n!}{prod_{i=1}^k a_i!} ]

    种分配方法。设 (f_i) 为大小为 (i) 的组的个数,(g_i) 表示结果,并且记 (F(x),G(x)) 为其 EGF。不难列出两者关系的式子:

    [g_n = sum_{kge 1} frac{1}{k!}left(sum_{sum a_i=n}dfrac{n!}{prod_{i=1}^k a_i!}prod_{i=1}^k f_{a_i} ight) \ dfrac{g_n}{n!} = sum_{kge 1} frac{1}{k!}left(sum_{sum a_i=n}prod_{i=1}^k dfrac{f_{a_i}}{a_i!} ight) ]

    其中括号中的正好是 ([x^n] F^k(x))。于是:

    [dfrac{g_n}{n!} = sum_{kge 1} dfrac{[x^n]F^k(x)}{k!} Leftrightarrow G(x) = sum_{kge 1} dfrac{F^k(x)}{k!} ]

    事实上,EGF 中的 (/i!) 并没有那么显然,是推式子推出来的结果。

    (exp,ln) 的计数只适用于指数生成函数,并且不能做无标号的计数。这是因为两个对象可能本质相同,不能简单的 (/i!),而有标号计数则因为标号必然不同。

    错排计数

    我们用置换环的角度考虑。对于一个排列 (p_1, p_2, cdots, p_n)(forall iin [1, n])(i)(p_i) 连边,所得的一堆环即为置换环。

    考虑一个置换环实际上就是一个圆排列。设 (F(x)) 为大小 (ge 2) 的圆排列数的 EGF,那么 (F(x)=sum_{ige 2} x_i/i)

    由上面的结论易知,答案的 EGF (G(x) = exp F(x) = exp(-ln(1-x)-x))

    51nod-1728 不动点

    求映射 (f:{1, 2, cdots, n} o {1, 2, cdots, n}) 满足

    [underbrace{fcirc fcirc cdots circ f}_{k} = underbrace{fcirc fcirc cdots circ f}_{k-1} ]

    的个数。(nkle 2 imes 10^6, kin[1, 3])

    首先需要看出这是一个有根森林的模型,并且树深不超过 (k)

    (F_i(x)) 为深度不超过 (i) 的森林的 EGF。那么:

    [F_i(x) = exp(xcdot F_{i-1}(x)) ]

    乘上 (x) 表示用一个那些旧的根向新的根连边,组合成一个深度不超过 (i) 的有根树。由于要求的是森林,那么外面套一个 (exp) 即可。

    对于本题,地推求 (F_k(x)) 即可得到答案,复杂度是 (O(kcdot nlog n)),需要做 (k)(exp)

    有标号基环树计数

    一个无向图为基环树,当且仅当其中存在恰好一个环且大小 (ge 3)。那么整个基环树可以看做是一个有根森林,然后用一个环串起来。

    由 Cayley 定理可得,有根树的 EGF 为 (F(x) = sumlimits_{ige 0} dfrac{n^{n-1}}{n!} x^i)。那么答案的 EGF

    [G(x) =frac{1}{2}sum_{kge 3} frac{F^k(x)}{k!}=-dfrac{1}{2}(ln (1- F(x)) - F(x)- F^2(x)) ]

    除以 (2) 是因为那个环可以翻转。

    有标号二分图计数

    设答案的 EGF 为 (G(x)),有标号二分连通图的 EGF 为 (F(x))。那么显然 (G(x)=exp F(x))

    设二分染色图的 EGF 为 (H(x)),这个图是很好数的:枚举黑色点的个数 (k),那么:

    [[x^n]H(x) = sum_{k=1}^n {nchoose k} 2^{k(n-k)} ]

    考虑 (G(x))(H(x)) 的关系:对于一个连通块,由于二分图的性质,当一个点的颜色确定,那整个连通块的黑白染色都是确定的。换言之,一个连通块的染色方案只有 (2) 种。那么枚举连通块个数 (k)

    [H(x)=sum_{kge 1} dfrac{2^kcdot F^k(x)}{k!} = exp 2F(x) \ G(x) = sqrt{H(x)} ]

    多项式开根可以 (O(nlog n)) 做,接下来的问题就是怎么算 (H(x)) 的系数。

    其中的组合数可以直接拆,然后就是卷积的形式,但 (2^{k(n-k)}) 不是很好搞。考虑其指数的组合意义:左边 (k),右边 (n-k) 个元素,左右各选 (1) 个的方案数。这相当于 (n) 个元素中直接选 (2) 个,减掉选出的两个都在左边或都在右边的方案数,即:

    [k(n-k) = {nchoose 2} -left( {kchoose 2} + {n-kchoose 2} ight) ]

    由于这是指数,所以指数相加时对应乘法,那么 (H(x)) 自然可以卷积求出了。

    LOJ-6570 毛毛虫计数

    求有多少个大小为 (n) 的有标号无根树,满足存在一条路径,使得任何一个点到路径的距离不超过 (1)

    一开始想了一个及其 fake 的做法,就用一个节去接上两条毛毛虫。但这接的位置很有讲究,不能接在中间,这里面情况就很复杂了。而接上之后还是有根的,还得考虑正反……

    实际上从一个个节开始考虑是最方便的。任意发现,一个大小为 (n) 的节就是一个菊花图然后定根。不难得到其 EGF:(A(x)=sumlimits_{ige 1} dfrac{x^i}{(i-1)!})。然后有先后顺序地拼接起来,得到答案的 EGF:(F(x)=frac{1}{2}sum_{ige 1} A^i(x)=dfrac{1}{2(1-A(x))})。除以 (2) 是因为正反。

    但这样是会重的:对于某个端点存在很多挂着的点时,会以这个端点一个点也不挂的形式再被算好多次。那索性钦定两端的节的点数 (ge 2)。设端点节的 EGF 为 (B(x)=sumlimits_{ige 2} dfrac{x^i}{(i-1)!}),于是:

    [F(x)=dfrac{B(x)^2}{2(1-A(x))} ]

    有标号仙人掌计数

    仙人掌的定义是,每条边最多属于一个简单环的无向连通图。

    考虑和树的计数一样的想法,先算有根,最后可以 (/n) 得到无根的结果。

    设答案 EGF 为 (F(x))。对于一个点,将其作为根,下面接着一坨东西,那么有两种情况:

    • 下方只有一条边和根向相邻,那么就是 (F(x))
    • 下方若干个仙人掌串成一条,然后两端向根连边。枚举仙人掌个数 (i),得 (frac{1}{2}sum_{ige 2}F^i(x))

    第一种情况下面可以有若干个仙人掌,而第二种下面也可以有若条仙人掌串,于是使用 (exp) 组合起来,得到一个方程:

    [F(x) =x expleft(F(x)+frac{1}{2}sum_{ige 2}F^i(x) ight) =x exp dfrac{2F(x)-F^2(x)}{2-2F(x)} ]

    然后我们要……解这个方程!首先设 (G(x) = xleft(exp frac{2F(x)-F^2(x)}{2-2F(x)} ight) -F(x)),然后尝试牛顿迭代。先求导:

    [egin{aligned} G'(F(x)) &= xleft(exp frac{2F(x)-F^2(x)}{2-2F(x)} ight)' - 1 \ &= xleft(exp frac{2F(x)-F^2(x)}{2F(x)-2} ight)left(frac{2F(x)-F^2(x)}{2-2F(x)} ight)' - 1 \ &= xleft(exp frac{2F(x)-F^2(x)}{2-2F(x)} ight)left(frac{(2-2F(x))^2 +2(2F(x)+F^2(x)) }{(2-2F(x))^2 } ight) - 1 end{aligned} ]

    化简到此处已经出现了大量重复的部分了,考虑换元使式子更简洁。设 (A(F(x))=2F(x)-F^2(x),B(F(x))=2-2F(x))。那么:

    [G'(F(x)) = xleft(expfrac{A(F(x))}{B(F(x))} ight)left(dfrac{B^2(F(x))+2A(F(x))}{B^2(F(x))} ight)-1 ]

    就行了牛迭的式子就不难写了:

    [egin{aligned} widehat F(x) &equiv F(x)-frac{G(F(x))}{G'(F(x))} pmod {x^{2n}} \ &equiv F(x)-dfrac{xleft(expfrac{A(F(x))}{B(F(x))} ight)-F(x)}{xleft(expfrac{A(F(x))}{B(F(x))} ight)left(frac{B^2(F(x))+2A(F(x))}{B^2(F(x))} ight)-1} pmod {x^{2n}} \ end{aligned} ]

    时间复杂度 (O(nlog n)),常数有点大。

    有标号 DAG 计数

    (n) 个点有标号 DAG 的个数为 (f_n),其 EGF 为 (F(x))。考虑在图中添加入度为 (0) 的点来构造 DAG,那么有:

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

    但这样会算重,比如 (2 o 1, 3 o 1) 这张图,会在 (i=1) 时算两次,在 (i=2) 时又算一次。考虑容斥原理:

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

    接下来只要求出 (f_1, f_2, cdots, f_n) 就行了。推式子:

    [egin{aligned} f_n &= sum_{i=1}^n (-1)^{i-1} {nchoose i} 2^{i(n-i)} f_{n-i} \ Leftrightarrow dfrac{f_n}{n!} &=sum_{i=1}^n dfrac{(-1)^{i-1}}{i!} imes dfrac{f_{n-i}}{(n-i)!} imes 2^{i(n-i)}\ Leftrightarrow dfrac{f_n}{2^{nchoose 2}n!} &=sum_{i=1}^n dfrac{(-1)^{i-1}}{2^{ichoose 2}i!} imes dfrac{f_{n-i}}{2^{n-ichoose 2}(n-i)!} end{aligned} ]

    可以发现数二分图时用到的一个处理 (2^{i(n-1)}) 的 trick 又派上用场了。现在这已经像个卷积形式了,但是有一点不同,因为 (f_n) 的值基于前面的项,分治 FFT 可以 (O(nlog^2 n)) 求解。然而我们还有复杂度更低的做法。

    (g_n = frac{(-1)^{n-1}}{2^{nchoose 2}n!})(G(x)) 为其生成函数。于是:

    [egin{aligned} F(x) equiv& F(x)G(x) - 1 pmod {x^{n}}\ F(x) equiv& frac{1}{G(x) - 1} pmod {x^{n}} end{aligned} ]

    可以多项式求逆,(O(nlog n))

    点双 & 边双连通图计数

    https://www.cnblogs.com/-Wallace-/p/vbcc-ebcc-counting.html

    有标号强连通图计数

    很大程度上收到了 这题 的启发,当然一些必要的部分还是写一下。(由于找不到测的地方所以只有口胡,如果出锅希望可以在评论区指出错误并把我 D 爆)

    设答案为 (f_n),EGF 为 (F(x))

    首先一个显然的正难则反,就是答案等于所有的图减去非强连通图个数。而一个图非强连通,当且仅当这个图进行强连通分量缩点之后是点数 (ge 2) 的 DAG。先写一下 (n) 个点的有标号 DAG 个数((a_n),EGF为 (A(x)))的式子:

    [a_n = sum_{i=1}^n (-1)^{i+1}{nchoose i} 2^{i(n-i)}cdot a_{n-i} ]

    具体解释可以参考上面链接。

    注意这里不能直接吧 (A(x)) 中的 (x) 换做 (F(x))(答案 EGF)然后复合逆,因为直接将一个点扩张之后会存在多个点可以连边,而这并不能直接复合函数体现。

    更加靠谱的做法应该是直接在上面的式子中把缩完之后的点扩张,那么得到的就是一般有标号有向图的个数,记作 (b_n)

    [b_n = sum_{i=1}^n 2^{i(n-i)}b_{n-i} sum_{k=1}^idfrac{(-1)^{k+1}}{k!} sum_{sum_{j}^k s_j=i} {ichoose s_1, s_2, cdots, s_k}prod_{j=1}^k f_{s_j} ]

    看上去很复杂,但是发现后面那一大坨就是 (sum_{kge 1} frac{(-1)^{k+1} F^{k}(x)}{k!})(x^i) 项系数 ( imes i!)。不妨设其为 (G(x)),易得 (G(x)=-exp(-F(x)))

    然后看到 (i)(n-i) 的一下就想到是要我们凑一个卷积形式。设 (C_1(x)=sum_{i} frac{b_i x^i}{i!cdot 2^{ichoose 2}}, C_2(x)=sum_{i} frac{b_i x^i}{i!}cdot 2^{ichoose 2},H(x)=sum_{i} [x^i]G(x)cdot frac{1}{2^{ichoose 2}})。于是显然:

    [C_2(x) = C_1(x)cdot H(x) ]

    多项式 (ln) 解这个方程即可。

  • 相关阅读:
    打造基于CentOS7的xfce最简工作环境
    Linux下C程序的编辑,编译和运行以及调试
    修正 XE6 TListView 上方 SearchBok 右边的清除钮显示
    TabControl 显示彩色的图示 (XE6 Firemonkey)
    TSwitch 中文简繁显示支持(XE6 Android)
    改变 TMemo 的背景颜色 (Firemonkey)
    修正 XE5 Android 键盘三个问题
    Delphi 收藏
    展示 Popup 的使用方法
    ListView 下拉更新 (支持 Android)
  • 原文地址:https://www.cnblogs.com/-Wallace-/p/count-by-egf.html
Copyright © 2011-2022 走看看