前言
最近看到一道经典的题目,就是这一题了。
题意:求 nnn 个点的无向连通图的个数。
题意很简洁,做法也很自然。因为本篇重点不在这一道题,因此这里只做一个简短的说明:
不妨设答案的生成函数为 ∑i=1∞fixi\sum\limits_{i=1}^{\infty} f_ix^ii=1∑∞fixi 。
我们知道我们可以取任意多任意大小的连通块生成一张无向图,而 nnn 个点的无向图个数共有 2n(n−1)22^{\frac{n(n-1)} {2}}22n(n−1) 个。
设 f(x)=∑i=1∞fii!xif(x)=\sum\limits_{i=1}^{\infty}\frac{f_i}{i!}x^if(x)=i=1∑∞i!fixi 。
根据指数型生成函数的知识我们有:ef(x)=∑i=0∞2i(i−1)2i!xie^{f(x)}=\sum\limits_{i=0}^{\infty} \frac{2^{\frac{i(i-1)} {2}}} {i!}x^ief(x)=i=0∑∞i!22i(i−1)xi
多项式求 ln\lnln 即可。
正文
显然,联通图可以理解为连通块个数等于 111 。
如果是连通块个数等于 kkk 的方案数,我们只需要求 fkf^kfk 就可以了,注意到同一张图会被生成 k!k!k! 次(生成的排列共有 k!k!k! 种),因此答案的指数型生成函数是 fkk!\frac{f^k} {k!}k!fk 。
那如果是连通块个数 ≤k\le k≤k 的方案数呢?
很显然,把 111 至 kkk 的函数求和即可(下文为了方便实际上还把函数加了一个常数 111 ,不过并没有什么影响):
G(x)=ex mod xk+1G(x)=e^x \bmod x^{k+1} G(x)=exmodxk+1
F(x)=G(f(x))=∑i=0kfi(x)i!F(x)=G(f(x))=\sum\limits_{i=0}^{k}\frac{f^i(x)} {i!}F(x)=G(f(x))=i=0∑ki!fi(x)
现在的问题在于如何求 F(x)F(x)F(x)。
暴力乘卷积优化的复杂度为 O(n2logn)O(n^2\log n)O(n2logn) 。
使用快速计算复合函数的算法的话,就是 O((nlogn)1.5)O((n\log n)^{1.5})O((nlogn)1.5) 。
当然,以上两种做法都没有用到 FFF 的特殊性质。
我们知道 exe^xex 的重要特性是导数与原函数相等。
而 G(f)=ef mod fk+1G(f)=e^f \bmod f^{k+1}G(f)=efmodfk+1
不妨对两边同时求导:
G′(f)=ef mod fkG'(f)=e^f \bmod f^{k}G′(f)=efmodfk
两式对减:
G(f)−G′(f)=fkk!G(f)-G'(f)=\frac{f^k} {k!}G(f)−G′(f)=k!fk
用 FFF 替换 GGG :
F(x)−F′(x)f′(x)=fk(x)k!F(x)-\frac{F'(x)} {f'(x)}=\frac{f^k(x)} {k!}F(x)−f′(x)F′(x)=k!fk(x)
这就是一个很典型的一阶微分方程了。
于是我们有:
F′(x)−F(x)f′(x)=−fk(x)f′(x)k!F'(x)-F(x)f'(x)=-\frac{f^k(x)f'(x)} {k!}F′(x)−F(x)f′(x)=−k!fk(x)f′(x)
e−f(x)(F′(x)−F(x)f′(x))=−fk(x)f′(x)e−f(x)k!e^{-f(x)}(F'(x)-F(x)f'(x))=-\frac{f^k(x)f'(x)e^{-f(x)}} {k!}e−f(x)(F′(x)−F(x)f′(x))=−k!fk(x)f′(x)e−f(x)
(F(x)e−f(x))′=−fk(x)f′(x)e−f(x)k!(F(x)e^{-f(x)})'=-\frac{f^k(x)f'(x)e^{-f(x)}} {k!}(F(x)e−f(x))′=−k!fk(x)f′(x)e−f(x)
因此有:
F(x)=ef(x)∫−fk(x)f′(x)e−f(x)k!dxF(x)=e^{f(x)}\int -\frac{f^k(x)f'(x)e^{-f(x)}} {k!}dxF(x)=ef(x)∫−k!fk(x)f′(x)e−f(x)dx
这样子就可以在 O(nlogn)O(n\log n)O(nlogn) 时间内求解了。
个人认为这个解题思路相当巧妙,可以优化许多类似问题。