一些典型的计数

这里将会记录一些典型的计数。

图计数

无向图计数

显然,\(n\) 个点的无向图个数应该为 \(2 ^ {\binom{n}{2}}\)

\(n\) 个点 \(m\) 条边无向图计数

不妨设 \(g(n, m)\) 表示 \(n\) 个点 \(m\) 条边的无向图个数,显然有

\[g(n, m) = \dbinom{\binom{n}{2}}{m} \]

\(f(n, m)\) 表示 \(n\) 个点 \(m\) 条边的无向连通图个数。对于无向图,枚举 \(1\) 号点相连的连通块大小以及边数,可以得到下面等式:

\[g(n, m) = \sum_{a \le n} \sum_{b \le m} \binom{n - 1}{a - 1} g(n - a, m - b) \times f(a, b) \]

\(f(n, m)\) 的项分离出来,我们可以得到:

\[\begin{array}{c} g(n, m) = f(n, m) +\sum \limits_{a < n} \sum\limits_{b \le m} \dbinom{n - 1}{a - 1} g(n - a, m - b) \times f(a, b)\\\\ + \sum\limits_{a \le n} \sum\limits_{b < m} \dbinom{n - 1}{a - 1} g(n - a, m - b) \times f(a, b)\\\\ - \sum\limits_{a < n} \sum\limits_{b < m} \dbinom{n - 1}{a - 1} g(n - a, m - b) \times f(a, b) \end{array} \]

这个公式看起来有点繁琐,不妨设 \(\mathcal{H}(n, m, x, y)\) 表示 \(\sum\limits_{a \le n} \sum\limits_{b \le m} \dbinom{n - 1}{a - 1} g(n - a, m - b) \times f(a, b)\),移项后不难得到:

\[f(n, m) = g(n, m) - h(n, m, n - 1, m) - h(n, m, n, m - 1) + h(n, m, n - 1, m - 1) \]

复杂度达到 \(O((nm) ^ 2)\)。使用斯特林反演可以做到 \(O(n ^ 2 m)\)

\(n\) 点无向连通图计数

和上面的思路基本相同。最暴力的思路是枚举 \(1\) 号节点所在连通块的大小。

不妨设 \(g(n)\) 表示 \(n\) 个点的 无向图 个数,\(f(i)\) 表示 \(n\) 个点的 无向连通图 个数,那么有:

\[g(n) = \sum_{i \le n} \dbinom{n - 1}{i - 1} f(i) g(n - i) \]

\(f(n)\) 分离并移项,可以得到:

\[f(n) = g(n) - \sum_{i < n}\dbinom{n - 1}{i - 1}f(i)g(n - i) \]

这个做法是 \(O(n ^ 2)\) 的。

接下来你发现,若设出 \(f, g\)\(\mathbf{EGF}\) 分别为 \(\mathcal{F, G}\),上述式子可以直接分治 NTT。这样可以做到 \(O(n \ \mathrm{polylog}(n))\) 的复杂度。

具体题目可以见 \(\texttt{ACW #307}\)

树的拓扑序计数

这里的树指的是一棵根向树。

  • 使用树形 \(\text{dp}\) 求解
    不妨设 \(f_u\) 表示以 \(u\) 为根的树的拓扑序计数。不妨设其有两个儿子 \(v_1, v_2\)。这里的转移不可以将 \(f_{v_1}, f_{v_2}\) 简单相乘,还应该考虑两个子树之间的错排顺序。考虑从 \(sz_{v_1} + sz_{v_2}\) 中选出 \(sz_{v_1}\) 个放在前面,其余的放在后面。那么有方程

\[f_{u} = f_{v_1} \times f_{v_2} \times \dbinom{sz_{v_1} +sz_{v_2}}{sz_{v1}} \]

推广到一般树,就有

\[f_{u} = (sz_u - 1)! \prod_{v \in son(u)} \dfrac{f_v}{sz_{v}!} \]

时间复杂度 \(O(n)\)

  • 使用生成函数求解

不妨设 \(\mathcal{[x ^ i]F_u(x)}\) 表示 \(u\) 子树选择了 \(i\) 个节点的拓扑序方案数。\(\mathcal{F}\) 为方案数的 \(\mathbf{EGF}\)。那么有

\[\mathcal{F_u(x)} = x \prod \mathcal{F_v(x)} \]

其中乘上 \(x\) 表示选择自己的方案数。

使用 NTT 即可做到 \(O(n \log n)\)。所求即为 \([x ^ n]\mathcal{F_1(x)}\)

二叉树计数

著名的卡特兰数。不妨设 \(f(i)\) 表示 \(i\) 个点的二叉树个数。那么有递推式:

\[f(n) = \sum f(i)f(n - i - 1) \]

这是卡特兰数的递推式,答案就是

\[C(n) = \dfrac{\dbinom{2n}{n}}{n + 1} \]

特殊二叉树计数

CF438E The Child and Binary Tree

给定集合 \(S\),每个节点权值需要 \(\in S\)。二叉树的权值定义为其所有节点的权值和。求权值为 \(m\) 的二叉树总数。

发现是上一道题的强化版。普通二叉树计数是这道题 \(S = \{1\}, m = n\) 的弱化版。

不妨设 \([x ^ n]f(x)\) 表示总和为 \(n\) 的满足条件的二叉树个数,\(g(x) = \sum [i \in S] x ^ i\),则有

\[f(x) = g(x) \times f(x) \times f(x) + 1 \]

其意义为:左子树方案为 \(f\),右子树方案为 \(f\),本身方案为 \(g\),加上空树。

解二次方程得到

\[f(x) = \dfrac{1 + \sqrt{1 - 4g(x)}}{2g(x)} \]

上多项式就可以了。如果嫌麻烦可以分子有理化一下。

竞赛图三元环计数

CF1264E Beautiful League

考虑容斥。如果是无向完全图,则三元环个数显然是 \(\dbinom{n}{3}\)。减去不合法的方案即可。

不合法的方案就是从 \(u\) 出发的两条同向边。所以总方案即为

\[\dbinom{n}{3} - \sum_u \dbinom{d_u}{2} \]

球盒问题

\(\texttt{Update on 2024/2/29}\):对某些进行了生成函数的理解。

若干个小球放进若干个盒子的方案计数。按照盒子 / 小球的限制分为

  • 小球有标号 / 无标号

  • 盒子有标号 / 无标号

  • 每个盒子至多放一个 / 至少放一个 / 无限制

共有 \(2 \times 2 \times 3 = 12\) 种选法。故称 \(12\) 球盒(\(12\) 重计数法)。

只能掌握比较简单的。比较困难的无法掌握。

小球有标号,盒子有标号,无限制

每个小球可以在 \(m\) 个盒子中选择。所以答案为 \(m \times m \cdots \times m = m ^ n\)

生成函数理解:由于小球和盒子都不相同,因此都考虑其 \(\mathbf{EGF}\)。盒子的 \(\mathbf{EGF}\)\(e ^ {x}\),则答案为

\[\left[\dfrac{x ^ n}{n !}\right] e ^ {mx} = m ^ n \]

小球有标号,盒子有标号,每个盒子至少放一个

考虑容斥。强制有 \(i\) 个盒子里没有球,那么 \(n\) 个球要放进剩下 \(m - i\) 个盒子里,方案数为 \((m - i) ^ n\)。由于盒子有标号,所以还要乘以一个 \(\binom{m}{i}\)。因此总方案数就是:

\[\sum \limits_{i = 0}^{m} (-1) ^ i \binom{m}{i} (m - i) ^ n \]

生成函数理解:每个盒子的 \(\mathbf{EGF}\)\(e ^ x - 1\),表示抠掉选 \(0\) 个的方案。答案即为

\[\left[\dfrac{x ^ n}{n !}\right] (e ^ x - 1) ^ m \]

使用二项式定理展开,可以得到:

\[\left[\dfrac{x ^ n}{n !}\right] (e ^ x - 1) ^ m = \left[\dfrac{x ^ n}{n !}\right] \sum_{i = 0}^{m} \dbinom{m}{i} e ^ {ix} (-1) ^ {m - i}\\=\left[\dfrac{x ^ n}{n !}\right]\sum_{i = 0}^{m} \dbinom{m}{i} i ^ {n} (-1) ^ {m - i} \]

小球有标号,盒子有标号,每个盒子至多放一个

如果 \(n > m\) 肯定无解。假设 \(n \le m\),那么有 \(m - n\) 个盒子是空的。选出这 \(m - n\) 个盒子,方案数为 \(\binom{m}{m - n}\)。由于小球有标号,所以还要乘以小球的排列数。答案即为:

\[n! \binom{m}{m - n} = n! \binom{m}{n} = m ^ {\underline{n}} \]

生成函数理解:每个盒子生成函数为 \(1 + x\),表示选 \(0 / 1\) 个。答案即为:

\[\left[\dfrac{x ^ n}{n !}\right] (1 + x) ^ m = m ^ {\underline{n}} \]

小球无标号,盒子有标号,每个盒子至少放一个

插板法。将 \(n\) 个小球排成一排,在 \(n - 1\) 个空里面插入 \(m - 1\) 个板子,分成 \(m\) 份。答案即为

\[\binom{n - 1}{m - 1} \]

生成函数理解:盒子的生成函数为 \(\dfrac{x}{1 - x}\)。这是由于每个盒子放 \(1 \sim + \infty\) 都有一种方案,其生成函数为 \(\dfrac{1}{1 - x}\)。但是去掉不放小球的方案,即为 \(\dfrac{1}{1 - x} - 1 = \dfrac{x}{1 - x}\)。所求即为

\[[x ^ n] \left(\dfrac{x}{1 - x}\right) ^ m = [x ^ n] \dfrac{x ^ m}{(1 - x) ^ m} = \dbinom{n - 1}{m - 1} \]

小球无标号,盒子有标号,无限制

插板法变形。将 \(n\) 个小球排成一排,在后面再加入 \(m\) 个小球,现在小球总数为 \(n + m\)。将 \(m - 1\) 个板子插到 \(n + m - 1\) 个空里,将小球分成 \(m\) 份。分完之后,再从每一组里抽走一个小球,即可将每个盒子至少放一个转化为每个盒子里放 \(\ge 0\) 个。总方案数即为:

\[\binom{n + m - 1}{m - 1} \]

生成函数理解:每个盒子的 \(\mathbf{OGF}\)\(\dfrac{1}{1 - x}\)

\[[x ^ n] \left(\dfrac{1}{1 - x}\right) ^ m = \dfrac{1}{(m - 1)!} \times (n + m - 1) ^ {\underline{m - 1}} = \dbinom{m +n - 1}{m - 1} \]

注:这里很有可能是不对的。

小球无标号,盒子有标号,每个盒子至多放一个

思路和 小球有标号,盒子有标号,每个盒子至多放一个 类似。如果 \(n > m\) 无解。然后从 \(m\) 个盒子里选出 \(n\) 个非空盒子即可。这里由于小球无标号,所以不需要乘以 \(n!\)。答案即为

\[\binom{m}{n} \]

小球有标号,盒子无标号,无限制

就是 第二类斯特林数

\({n \brace m}\) 表示 \(n\) 个有标号小球放进 \(m\) 个盒子(盒子非空)的方案数,则有递推

\[{n \brace m} = {n - 1 \brace m - 1} + m \times {n - 1 \brace m} \]

对于该式的理解:第 \(n\) 个小球单独放一个盒子,加上和其他 \(n - 1\) 个小球放一个盒子。

可以做到 \(O(n ^ 2)\) 的递推。多项式做法已经不想懂了。

对于该题,答案即为

\[\sum_{i \le m} {n \brace i} \]

小球有标号,盒子无标号,每个盒子至多放一个

能放下就是 \(1\),否则就是 \(0\)

小球有标号,盒子无标号,每个盒子至少放一个

和第二类斯特林数定义相同。方案即为

\[{n \brace m} \]

小球无标号,盒子无标号,每个格子至多放一个

能放下就是 \(1\),否则就是 \(0\)

小球无标号,盒子无标号,无限制

定义“划分数” \(P(n, m)\),表示将 \(n\) 划分成 \(m\) 个非负整数的方案数。则有

\[P(n, m) = P(n - m, m) + P(n, m - 1) \]

对于这个式子的理解:显然,对于划分出来的所有数都为整数的情况,将他们全部减一,可以建立到 \(P(n - m, m)\) 的双射。对于有 \(0\) 的情况,可以看做在后面加了一个零进去,方案数为 \(P(n, m - 1)\),加入多个零可以通过这个递归定义。

显然可以多项式,但是我已经不想学了。所以这是一个 \(O(n ^ 2)\) 的算法。

小球无标号,盒子无标号,每个盒子至少放一个

将每个盒子里先钦定一个球,然后就是上一问的做法。方案数即为

\[P(n - m, m) \]

其他计数

错排数

对于一个排列 \(p\),若满足 \(\forall i \le n, p_i \ne i\),则称 \(p\) 为长度为 \(n\) 的一个错排。

\(D_n\) 表示长度为 \(n\) 的错排的个数。有递推式:

\[D_n = (n - 1)(D_{n - 1} + D_{n - 2}) \]

对这个递推式的解释:考虑第 \(n\) 个数放在那里。显然不能放在位置 \(n\)。假设放在了位置 \(i\),则位置 \(i\) 的数有两种选择:放在 \(n\) 和不放在 \(n\)。对于放在 \(n\),剩下的方案数就是 \(D_{n - 2}\),对于不放在 \(n\),剩下的方案就是 \(D_{n - 1}\)。枚举 \(i\)\(n - 1\) 中选择。故有上式。

部分错排数

对于长度为 \(n\) 的,有 \(m\) 个数错排的排列进行计数。

首先选出 \(m\) 个错排的数,再乘上错排数即可。方案数即为

\[\dbinom{n}{m} D_{m} \]

卡特兰数

上文中二叉树的计数使用了卡特兰数。其符号一般记做 \(C(n)\)

卡特兰数有递推式:

\[C(n) = \sum_{i < n} C(i)C(n - i - 1) \]

通过生成函数等方法,我们可以求出他的另外两个表达式。这两种表达式允许 \(O(1)\) 地计算其值。

  • \(C(n) = \dfrac{\dbinom{2n}{n}}{n + 1}\)

  • \(C(n) = \dbinom{2n}{n} - \dbinom{2n}{n - 1}\)

卡特兰数最典型的模型是这样的:在 \(n \times n\) 的网格图中,从原点出发到 \((n, n)\) 点,不经过直线 \(y = x\) 的路径数目。其他问题大多可以转化为这个模型。

卡特兰数典型问题:

  • 某些网格路径计数

  • 合法括号计数

  • 二叉树计数

  • 多边形三角形划分

第一类斯特林数

\(n\) 个不同元素划分为 \(m\) 个圆排列的方案数,记做 \(\Large{n \brack m}\)

考虑递推求第一类斯特林数。有递推式:

\[{n \brack m} = {n - 1 \brack m - 1} + (n - 1) {n - 1 \brack m} \]

对该公式的理解:第 \(n\) 个元素有两种放法:自己单独成为一个圆排列或者与前面的元素共同构成圆排列,这分别对应上式中的两项。

read(n, m); S[0][0] = 1;
rep(i, 1, n) rep(j, 1, m)
    S[i][j] = (S[i - 1][j - 1] + (i - 1) * S[i - 1][j] % mod) % mod;
printf("%lld\n", S[n][m]); return 0;

第二类斯特林数

\(12\) 重计数法中有提到。其定义为:将 \(n\) 个不同元素划分成 \(m\) 个非空集合的方案数。递推式为:

\[{n \brace m} = {n - 1 \brace m - 1} + m \times {n - 1 \brace m} \]

其理解可以查阅上文球盒问题小球有标号,盒子无标号部分。

read(n, k); S[0][0] = 1;
rep(i, 1, n) rep(j, 1, k)
    S[i][j] = (S[i - 1][j - 1] + j * S[i - 1][j] % mod) % mod;
printf("%lld\n", S[n][k]); return 0;

贝尔数

\(B(n)\) 表示将 \(n\) 个不同元素划分成若干个非空子集的方案数。

很显然的,我们已经有了一个 \(O(n ^ 2)\) 的递推式。根据第二类斯特林数,我们只需要将斯特林数行求和即可。故有

\[B(n) = \sum_{k \le n} {n \brace k} \]

下面介绍另一个递推公式:

\[B(n + 1) = \sum_{k \le n} \binom{n}{k} B(k) \]

对于这个公式的理解:对于第 \(n + 1\) 个数,如果其单独被分到一类,剩下 \(n\) 个,则方案数为 \(\dbinom{n}{n} B(n)\)。如果和某一个分到一个集合,则剩下 \(n - 1\) 个,方案数为 \(\dbinom{n}{n - 1} B(n - 1)\)。以此类推。

B[0] = 1;
rep(i, 1, n) rep(k, 0, i - 1) (B[i] += B[k] * C(i - 1, k) % mod) %= mod;

不同计数常见值

省选临近,最重要的事情莫过于学会各种乱搞技巧。

对于计数题,最常见的方法是打表 + 瞎几把凑系数。所以能够通过表观察出系数是很重要的能力。

下面给出一些常见系数的表:

  • 第一类斯特林数

\[\begin{matrix} & \color{red}0 & \color{red}1 & \color{red}2 & \color{red}3 & \color{red}4 & \color{red}5 \\\\ \color{red}0 & 1 & \\ \color{red}1 & 0 & 1 & \\ \color{red}2 & 0 & 1 & 1 & \\ \color{red}3 & 0 & 2 & 3 & 1 & \\ \color{red}4 & 0 & 6 & 11 & 6 & 1 & \\ \color{red}5 & 0 & 24 & 50 & 35 & 10 & 1 & \\ \end{matrix} \]

  • 第二类斯特林数

\[\begin{matrix} & \color{red}0 & \color{red}1 & \color{red}2 & \color{red}3 & \color{red}4 & \color{red}5 \\\\ \color{red}0 & 1 & \\ \color{red}1 & 0 & 1 & \\ \color{red}2 & 0 & 1 & 1 & \\ \color{red}3 & 0 & 1 & 3 & 1 & \\ \color{red}4 & 0 & 1 & 7 & 6 & 1 & \\ \color{red}5 & 0 & 1 & 15 & 25 & 10 & 1 & \\ \end{matrix} \]

  • 卡特兰数

\[\begin{matrix} \color{red}0 & \color{red}1 & \color{red}2 & \color{red}3 & \color{red}4 & \color{red}5 & \color{red}6\\ 1 & 1 & 2 & 5 & 14 & 42 & 132 \end{matrix} \]

  • 错排数

\[\begin{matrix} \color{red}0 & \color{red}1 & \color{red}2 & \color{red}3 & \color{red}4 & \color{red}5 & \color{red}6\\ 0 & 0 & 1 & 2 & 9 & 44 & 265 \end{matrix} \]

  • 划分数

\[\begin{matrix} & \color{red}0 & \color{red}1 & \color{red}2 & \color{red}3 & \color{red}4 & \color{red}5 \\ \color{red}0 & 1 & 1 & 1 & 1 & 1 & 1 \\ \color{red}1 & 0 & 1 & 1 & 1 & 1 & 1 \\ \color{red}2 & 0 & 1 & 2 & 2 & 2 & 2 \\ \color{red}3 & 0 & 1 & 2 & 3 & 3 & 3 \\ \color{red}4 & 0 & 1 & 3 & 4 & 5 & 5 \\ \color{red}5 & 0 & 1 & 3 & 5 & 6 & 7 \\ \end{matrix} \]

  • 贝尔数

\[\begin{matrix} \color{red}0 & \color{red}1 & \color{red}2 & \color{red}3 & \color{red}4 & \color{red}5 & \color{red}6 & \\ 1 & 1 & 2 & 5 & 15 & 52 & 203 & \end{matrix} \]

posted @ 2024-02-28 21:13  Link-Cut-Y  阅读(439)  评论(6)    收藏  举报