【多项式·应用篇】有标号DAG计数问题
\(Preface\)
本文的核心内容很简单,就是围绕求\(n\)个点的有标号\(DAG\)个数展开的一系列讨论。
\(Problem\) \(1\)-\(1\)
- 求\(n\)个点的有标号\(DAG\)个数。
- 可以不连通。
- \(n\le5000\)
看数据范围显然只要用\(O(n^2)\)的做法就可以了。
考虑\(DAG\)中必然存在入度为\(0\)的点,且去掉这些入度为\(0\)的点之后得到的依然是\(DAG\)。
于是,我们可以设\(f_i\)表示\(i\)个点的有标号\(DAG\)数目,枚举一个\(j\)表示至少存在\(j\)个入度为\(0\)的点。
显然有此时的方案数为:
即,枚举选出哪\(j\)个点,枚举入度为\(0\)的点和其他点之间的边是否选择,而其他点依然形成\(DAG\)可以直接从已有状态转移。
看到至少,我们可以考虑容斥。
因此得到最终的转移方程:
\(Problem\) \(1\)-\(2\)
- 求\(n\)个点的有标号\(DAG\)个数。
- 可以不连通。
- \(n\le10^5\)
进一步考虑上面得到的式子,发现\(2^{j\times(i-j)}\)这个东西很难处理。
这需要一个据说算是套路的转化:
也就是说,原式就相当于:
即:
令\(F(x)=\sum_{i=0}^n\frac{f_i}{i!\times\sqrt2^{i^2}}x^i,G(x)=\sum_{i=1}^n\frac{(-1)^{i-1}}{i!\times\sqrt2^{i^2}}x^i\),便有:
稍微转化一下就能得到:
\(Problem\) \(2\)-\(1\)
- 求\(n\)个点的有标号\(DAG\)个数。
- 要求弱连通。
- \(n\le5000\)
首先我们依然要求出\(f_i\)。
然后我们再设一个\(g_i\),转移时去枚举\(1\)号点所在弱连通块大小,可得:
\(Problem\) \(2\)-\(2\)
- 求\(n\)个点的有标号\(DAG\)个数。
- 要求弱连通。
- \(n\le10^5\)
发现\(g_i=C_{i-1}^{i-1}g_if_{i-i}\),恰好能和\(\sum\)这一项拼在一起,也就是:
拆开组合数得到:
令\(F(x)=\sum_{i=0}^n\frac{f_i}{(i-1)!}x^i,G(x)=\sum_{i=0}^n\frac{g_i}{(i-1)!}x^i,H(x)=\sum_{i=0}^n\frac{f_i}{i!}x^i\),便有:
因此:
\(Postscript\)
好吧,余对于多项式这类问题终究还是不够熟练,仍需加强练习,唔姆。