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) 解这个方程即可。

  • 相关阅读:
    Hibernate,get()和load()区别
    Hibernate,Session方法使得java对象进入持久化状态;持久化对象特征
    Hibernate,Session清理缓存时间点
    frameset子窗口获取父窗口失败原因?
    struts2,实现Ajax异步通信
    struts2-json-plugin插件实现异步通信
    Hibernate,JPA注解@ManyToMany_JoinTable
    Hibernate,JPA注解@ManyToMany
    SparkStreaming操作Kafka
    DirectStream、Stream的区别-SparkStreaming源码分析02
  • 原文地址:https://www.cnblogs.com/-Wallace-/p/count-by-egf.html
Copyright © 2011-2022 走看看