2025.6 做题记录
2025.6.6
1. 洛谷 P8367 [LNOI2022] 盒
原题链接:https://www.luogu.com.cn/problem/P8367
首先考虑对于一组特定的 \((b_1, b_2, \cdots, b_n)\),怎么求它的最小代价。考虑拆贡献,将这 \(n\) 个盒子视作一条链,对每条边 \((i, i + 1)\) 求出这条边至少需要经过多少次。把所有盒子分成两个集合 \([1, i], [i + 1, n]\),记 \(a\) 的前缀和数组为 \(A\),\(b\) 的前缀和数组为 \(B\),那么我们需要在这个集合间交换至少 \(|A_i - B_i|\) 次货物才能使集合内部货物的数量满足条件。也就是说至少需要经过 \(|A_i - B_i|\) 次边 \((i, i + 1)\),那么总代价的下界即为 \(\sum_{i = 1}^{n - 1} |A_i - B_i|w_i\),通过从左到右依次满足每个盒子的限制的方法即可达到该下界。
然后考虑如何求解原问题,还是考虑把贡献拆到每条边上。显然一条边 \((i, i + 1)\) 的贡献只与变量 \(B_i\) 的值有关。考虑枚举 \(B_i\) 的值 \(j\),那么这条边的贡献即为 \(|j - A_i| w_i\),而使 \(B_i = j\) 的方案数可以通过隔板法算出,为 \(\binom{j + i - 1}{i - 1} \binom{S - j + n - i - 1}{n - i - 1}\)。因此一条边的总贡献即为 \(w_i \sum_{j = 0}^S \binom{j + i - 1}{i - 1} \binom{S - j + n - i - 1}{n - i - 1} |j - A_i|\),将 \(n - 1\) 条边的贡献累加即可得到答案,复杂度为 \(\Theta(\sum nS)\),期望得分 40 分。
考虑优化,我们希望快速计算 \(\sum_{j = 0}^S \binom{j + i - 1}{i - 1} \binom{S - j + n - i - 1}{n - i - 1} |j - A_i|\) 的值。分类讨论 \(j, A_i\) 的大小关系,将绝对值拆开,我们需要快速求出以下 4 个式子的值:
- \(\sum_{j = 0}^S \binom{j + i - 1}{i - 1} \binom{S - j + n - i - 1}{n - i - 1}\)
- \(\sum_{j = 0}^S \binom{j + i - 1}{i - 1} \binom{S - j + n - i - 1}{n - i - 1} j\)
- \(\sum_{j = 0}^{A_i} \binom{j + i - 1}{i - 1} \binom{S - j + n - i - 1}{n - i - 1}\)
- \(\sum_{j = 0}^{A_i} \binom{j + i - 1}{i - 1} \binom{S - j + n - i - 1}{n - i - 1} j\)
对于式 2、4,可以通过经典公式 \(a \binom{a - 1}{b - 1} = b \binom{a}{b}\) 转化为式 1、3 的形式,因此不再赘述。
对于式 1,经典地,考虑分析其组合意义:在 \(S + n - 1\) 个有标号物品中选出 \(n - 1\) 个,我们枚举从左往右数第 \(i\) 个被选物品的编号,记其为 \(j + i\)。一方面,从局部看,第 \(i\) 个被选物品为 \(j + i\) 的方案数为 \(\binom{j + i - 1}{i - 1} \binom{S - j + n - i - 1}{n - i - 1}\),因为前 \(i - 1\) 个物品需要在 \([1, j + i - 1]\) 中选取,后 \(n - i - 1\) 个物品需要在 \([j + i + 1, S + n - 1]\) 中选取。由于第 \(i\) 个被选物品一定在 \([i, S + i]\) 中,因此 \(j\) 取遍 \([0, S]\) 即可得到总方案数。另一方面,总方案数就是从 \(S + n - 1\) 个有标号物品中选出 \(n - 1\) 个的方案数,因此式 1 可以直接写成 \(\binom{S + n - 1}{n - 1}\)。
重点是对于式 3 该如何处理。当然我们还是可以类似式 1 地分析组合意义,但这里的 \(j\) 并没有取遍 \([0, S]\),而是只取到了 \([0, A_i]\),那么分析出的组合意义就要加上“第 \(i\) 个被选物品的编号不超过 \(A_i + i\)”的限制,因此不能直接写成组合数。考虑将限制改写一下,变成“要在前 \(A_i + i\) 个物品中选至少 \(i\) 个物品”,那么考虑枚举在 \([1, A_i + i]\) 中到底选了多少个物品,可以得到如下等式:
可是得到了这个等式好像也没什么用,因为每一项仍然是两个组合数相乘的形式。事实上,我们发现这个式子并不是很好化简,因此我们考虑借鉴处理 \(g(n, m) = \sum_{i = 0}^m \binom{n}{i}\) 的思路,构建一个关于答案的递推式。回忆一下我们是怎么处理 \(g(n, m)\) 的:
- \(g(n, m) = g(n, m - 1) + \binom{n}{m}\),
- \(g(n, m) = \sum_{i = 0}^m \binom{n - 1}{i} + \sum_{i = 0}^m \binom{n - 1}{i - 1} = \sum_{i = 0}^m \binom{n - 1}{i} + \sum_{i = 0}^{m - 1} \binom{n - 1}{i} = 2g(n - 1, m) - \binom{n - 1}{m}\)。
因此从 \(g(n, m - 1), g(n - 1, m)\) 递推到 \(g(n, m)\) 都可以 \(\Theta(1)\) 解决,于是可以使用莫队维护出所有要求的 \(g(n, m)\) 值。而对于本题,可以发现带求式中出现的变量只有 \(i, A_i\),因此我们可以把带求式记作 \(f(i, A_i)\)。我们想办法构建 \(f(i, A_i)\) 的递推式,由上面得出的等式有:
- \(f(i, A_i) = \sum_{j = 0}^{A_i} \binom{j + i - 1}{i - 1} \binom{S - j + n - i - 1}{n - i - 1} = f(i, A_i - 1) + \binom{A_i + i - 1}{i - 1} \binom{S - A_i + n - i - 1}{n - i - 1}\)
- \(f(i, A_i) = \sum_{j = i}^{n - 1} \binom{A_i + i}{j} \binom{S - A_i + n - i - 1}{n - j - 1} = f(i - 1, A_i + 1) - \binom{A_i + i}{i - 1} \binom{S - A_i + n - i - 1}{n - i}\)
- \(f(i, A_i) = f(i - 1, A_i + 1) - \binom{A_i + i}{i - 1} \binom{S - A_i + n - i - 1}{n - i} = f(i - 1, A_i) + \binom{A_i + i - 1}{i - 2} \binom{S - A_i + n - i - 1}{n - i} - \binom{A_i + i}{i - 1} \binom{S - A_i + n - i - 1}{n - i} = f(i - 1, A_i) - \binom{A_i + i - 1}{i - 1} \binom{S - A_i + n - i - 1}{n - i}\)
因此从 \(f(i - 1, A_i), f(i, A_i - 1)\) 到 \(f(i, A_i)\) 的转移也可以完成。事实上,由于本题的 \(n - 1\) 次查询中 \(i, A_i\) 均单调不减,因此这样的转移只需要 \(\Theta(n + S)\) 次,完全可以通过。总时间复杂度即为 \(\Theta(\sum n + \sum S)\)。
2. 方幂转下降幂、上升幂
证明:对于下降幂,令 \(x^n = \sum_{i = 0}^n A(n, i) x^\underline{i}\),其中 \(A(n, i)\) 的值与 \(x\) 无关,那么有
因此有递推式 \(A(n, i) = A(n - 1, i - 1) + i \cdot A(n - 1, i)\),且初始值 \(A(0, 0) = 1\)。发现这与第二类斯特林数的递推式相符,因此 \(A(n, i) = \begin{Bmatrix} n \\ i \end{Bmatrix}\)。
对于上升幂,仍旧令 \(x^n = \sum_{i = 0}^n B(n, i) x^\overline{i}\),同理可得递推式 \(B(n, i) = B(n - 1, i - 1) - i \cdot B(n - 1, i)\) 且初始值 \(B(0, 0) = 1\)。发现这与 \(A\) 递推式的区别仅在于 \(i \cdot B(n - 1, i)\) 的符号,此时我们运用凑奇偶性的思想,将递推式变形得 \((-1)^{n - i} B(n, i) = (-1)^{n - i} B(n - 1, i - 1) + i \cdot (-1)^{n - i - 1} B(n - 1, i)\)。此时该式与第二类斯特林数的递推式相符,因此 \(B(n, i) = (-1)^{n - i} \begin{Bmatrix} n \\ i \end{Bmatrix}\)。
3. 下降幂的“二项式定理”
证明:根据 \(\binom{x}{i} = \frac{x^\underline{i}}{i!}\),有
4. CF1097G Vladislav and a Great Legend
原题链接:https://www.luogu.com.cn/problem/CF1097G
5. CF917D Stranger Trees
原题链接:https://www.luogu.com.cn/problem/CF917D
2025.6.8
1. ABC409G Accumulation of Wealth
原题链接:https://atcoder.jp/contests/abc409/tasks/abc409_g
\(c_x\) 的变化过程大体可以分为两个阶段:先通过 \(x - 1\) 次操作 1 使得元素 \(x\) 出现,再通过若干次操作 2 使得元素 \(x\) 的出现次数不断增加。
先看第二阶段,对于任意元素 \(x\),设 \(f(k)\) 表示在“元素 \(x\) 在第 \(k\) 步操作后第一次出现”的条件下,最终出现次数的期望值。显然 \(k\) 步操作后 \(A\) 序列中恰有 \(k + 1\) 个元素,如果此时 \(x\) 出现了 \(c_x\) 次,那么下一步 \(c_x\) 增加 \(1\) 的概率为 \((1 - p) \cdot \frac{c_x}{k + 1}\),而保持不变的概率为 \(1 - (1 - p) \cdot \frac{c_x}{k + 1}\)。看上去由于这个概率的值与自变量 \(c_x\) 有关,因此 \(f(k)\) 难以转移,但事实上如果动手推一下式子就会发现,\(c_x\) 在第 \(k + 1\) 次操作后的期望值为
我们惊讶地发现 \(c_x\) 期望值的变化只是乘了一个常数而已,因此仍然是可以转移的。根据期望的可加性,我们可以得到 \(c_x\) 在第 \(k + 2\) 次操作后的期望值为 \(\frac{k + 2 - p}{k + 1} \cdot \frac{k + 3 - p}{k + 2} \cdot c_x\),第 \(k + 3\) 次后为 \(\frac{k + 2 - p}{k + 1} \cdot \frac{k + 3 - p}{k + 2} \cdot \frac{k + 4 - p}{k + 3} \cdot c_x\),以此类推。而 \(f(k)\) 的含义即为在“第 \(k\) 次操作后 \(c_k = 1\)”的条件下,第 \(n - 1\) 次操作后的期望值,因此
由于我们需要求出 \(f(0), f(1), \cdots, f(n - 1)\) 的所有值,而已知 \(f(n - 1) = 1\),因此我们可以根据 \(f(k + 1)\) 的通项公式建立递推式 \(f(k) = \frac{k + 2 - p}{k + 1} f(k + 1)\),这样这 \(n\) 个值就可以在 \(\Theta(n)\) 的时间复杂度内全部算出。
再来看第一阶段,记 \(g(k)\) 表示答案,即 \(n - 1\) 次操作后 \(c_k\) 的期望值。显然 \(g(1) = f(0)\),对于其他元素 \(k\),考虑通过枚举 \(k\) 第一次出现的时间来得到答案,令 \(k\) 第一次出现的时间为第 \(i\) 次操作后,那么第 \(i\) 次操作恰好执行的是第 \(k - 1\) 次操作 1,因此
令代数式 \(S(x) = \sum_{i = 0}^{n - 2} i!f(i + 1)x^i\),\(T(x) = \sum_{i = 0}^{n - 2} \frac{(1 - p)^i}{i!} \cdot x^{-i}\),那么 \(g(k)\) 的值即为 \(S(x) \cdot T(x)\) 中 \(x^{k - 2}\) 项系数的 \(\frac{p^{k - 1}}{(k - 2)!}\) 倍,只需将 \(T(x)\) 乘上 \(x^{n - 2}\) 后使用 NTT 优化卷积即可。
时间复杂度为 \((n \log n)\)。这道题告诉我们如果某个自变量 \(x\) 执行操作的概率与 \(x\) 自身的值有关,那么操作后 \(x\) 的期望值可能只是从通常的“加上某个常数”变成“乘上某个常数”,此时 \(x\) 期望值的转移仍然具有线性性。
2. 洛谷 P8990 [北大集训 2021] 小明的树
原题链接:https://www.luogu.com.cn/problem/P8990
核心在于把题目的条件转化成边与点的关系。一棵树是美丽的等价于“至少有一个端点被点亮的边数”等于“被点亮的结点数”,连通块数等于“被点亮的结点数”减去“两端都被点亮的边数”,而被点亮的结点数又与进行点灯操作的时间相等。
令 \(w_1(t)\) 表示 \(t\) 时刻“至少有一个端点被点亮的边数”减去“被点亮的结点数”(即 \(t\))的值,\(w_2(t)\) 表示 \(t\) 时刻“被点亮的结点数”(即 \(t\))减去“两端都被点亮的边数”的值,\(b_u\) 表示 \(u\) 被点亮的时间。那么一条边 \((u, v)(b_u < b_v)\) 对 \(w_1\) 的贡献相当于 \([b_u, n)\) 区间加 \(1\),对 \(w_2\) 的贡献相当于 \([b_v, n)\) 区间减 \(1\)。答案即为满足 \(w_1(t) = 0\) 的 \(w_2(t)\) 之和,而我们又发现对任意 \(t\) 都有 \(w_1(t) \geq 0\),因此直接用线段树维护 \(w_1(t)\) 取到最小值时 \(w_2(t)\) 的和即可。
时间复杂度为 \(\Theta(n \log n)\)。
2025.6.13
1. AGC017F Zigzag
原题链接:https://www.luogu.com.cn/problem/AT_agc017_f
考虑状压 DP,用 \(n - 1\) 位的二进制数表示折线,其中第 \(i(i \geq 0)\) 位为 \(0 / 1\) 表示折线在第 \(i + 1\) 层向左拐 / 向右拐。设 \(f_1(i, S)\) 表示只考虑从左往右数前 \(i\) 条折线,且第 \(i\) 条折线为 \(S\) 的方案数,转移时枚举第 \(i + 1\) 条折线是什么,时间复杂度为 \(\Theta(4^n m)\),显然过不去。
优化 1:经典地,将状压 DP 换成轮廓线 DP。设 \(f_2(i, j, S, T, x)\) 表示当前考虑到第 \(i\) 条折线的第 \(j\) 层,当前折线的前 \(j\) 层构成二进制数 \(S\),上一条折线的后 \(n - j\) 层构成二进制数 \(T\),且上一条折线的第 \(j\) 层在结点 \((j, x)\) 上的方案数,这样设状态能够唯一确定第 \(i\) 条折线第 \(j\) 层之后的限制。转移考虑枚举第 \(i\) 条折线的第 \(j + 1\) 层向左拐还是向右拐,时间复杂度为 \(\Theta(2^n mn^2)\),还是过不去。
优化 2:考虑我们记录上一条折线信息的目的,即确定第 \(i\) 条折线在第 \(j\) 层之后的左边界。我们不妨抛开上一条折线的信息,转而直接记录这个左边界,设 \(f_3(i, j, S)\) 表示考虑到第 \(i\) 条折线的前 \(j\) 层,且在前 \(j\) 层已经确定的前提下,第 \(i\) 条折线可能的字典序最小的走法为 \(S\) 的方案数。转移依旧考虑枚举下一层向哪边走,时间复杂度为 \(\Theta(2^n mn)\),可以通过。
2. CF1924D Balanced Subsequences
原题链接:https://www.luogu.com.cn/problem/CF1924D
不妨将一个括号序列转化为一条从 \((0, 0)\) 出发的折线,其中左括号意味着从 \((x, y)\) 走到 \((x + 1, y + 1)\),右括号意味着从 \((x, y)\) 走到 \((x + 1, y - 1)\)。令一个括号序列由 \(n\) 个左括号和 \(m\) 个右括号构成,且最长合法括号序列的长度为 \(k\)。那么有结论:它对应折线最低点的纵坐标为 \(m - k\)。
为什么这个结论是对的呢?考虑存在长度为 \(2i\) 的合法子序列当且仅当,从原序列中取出前 \(i\) 个左括号和后 \(i\) 个右括号,它们构成的括号序列是合法的。考虑不断地增加 \(i\) 并观察折线的变化,如果当 \(i = k + 1\) 时这个括号序列第一次不合法,那么此时折线的最低点纵坐标为 \(-1\),且剩余的 \(m - k - 1\) 个右括号均在该点的左边,\(n - k - 1\) 个左括号均在该点的右边。那么每恢复一个右括号都会使纵坐标减 \(1\),而每恢复一个左括号对它没有影响,于是这个结论就成立了。
那么剩下的问题就简单了,答案即为“折线与直线 \(y = k - m\) 有交的方案数”减去“折线与直线 \(y = k - m - 1\) 有交的方案数”,使用反射容斥即可。时间复杂度为 \(\Theta(T + \max\{n + m\})\)。
3. Min-Max 容斥
(1) 一般形式
证明:将 \(S\) 中的数从小到大排列,记为 \(a_1, a_2, \cdots, a_n\)。那么 \(a_i\) 作为最小值的条件为 \(T\) 必须包含 \(a_i\),且必须不包含 \(a_1, a_2, \cdots, a_{i - 1}\),对于其他数任意。因此由二项式定理,\(a_i\) 作为最小值的贡献为
(2) Min-kMax 容斥
记 \(\operatorname{kmax} S\) 表示 \(S\) 中第 \(k\) 大的元素,有
证明:将 \(S\) 中的数从小到大排列后记为 \(a_1, a_2, \cdots, a_n\),那么对于至少有 \(k\) 个元素的集合,其最小值显然至多为 \(a_{n - k + 1}\)。同理,\(a_i(i \leq n - k + 1)\) 作为最小值的贡献为
(3) 期望意义下的 Min-Max 容斥
现有 \(n\) 个随机变量 \(x_1, x_2, \cdots, x_n\),它们可能不是相互独立的。记它们构成的可重集为 \(S\),那么有
证明:将每一种可能的 \(x\) 序列罗列出来,计算出现这种情况的概率、最大值、每个子集的最小值。显然对于每种情况的后面两者,Min-Max 容斥的公式都成立,那么对于它们的带权和(等式两边乘的概率相等),Min-Max 容斥的公式也应当成立。
4. HDU4336 Card Collector
原题链接:https://vjudge.net/problem/HDU-4336
令随机变量 \(x_i\) 表示第一次搜集到第 \(i\) 张卡片的时间,令 \(S\) 为可重集 \(\{x_1, x_2, \cdots, x_n\}\) 的任意非空子集。那么 \(\max S\) 表示的是拥有 \(S\) 中所有卡片的期望时间,\(\min S\) 表示的是第一次拥有 \(S\) 中某张卡片的期望时间。
我们发现 \(E(\min S)\) 是好求的。令 \(p(S) = \sum_{x_i \in S} p_i\) 表示随机买一包零食,含有 \(S\) 中卡片的概率。显然 \(\min S \geq x\) 当且仅当买的前 \(x - 1\) 包零食中都不含 \(S\) 中的卡片,那么根据期望的线性性有
而答案即为 \(E(\max \{x_1, x+2, \cdots, x_n\})\),因此直接使用 Min-Max 容斥即可,时间复杂度为 \(\Theta(\sum 2^n)\)。
双倍经验:洛谷 P3175 [HAOI2015] 按位或,唯一的区别就是在这道题中多张卡片可以一起选,因此在求 \(p(S)\) 前做一遍高维前缀和即可,时间复杂度为 \(\Theta(2^n n)\)。
2025.6.15
1. 树的拓扑序计数
对于一棵 \(n\) 个点的外向树,令 \(\mathrm{size}(u)\) 表示 \(u\) 的子树大小,那么该外向树的拓扑序个数为
证明:令 \(p\) 为 \(u\) 子树内所有结点的一个排列,那么 \(p\) 是 \(u\) 子树的某个拓扑序当且仅当
- \(p_1 = u\);
- 对 \(u\) 的每个儿子 \(v\),令 \(q\) 为 \(p\) 中所有在 \(v\) 子树内的元素构成的子序列,那么 \(q\) 也是 \(v\) 子树的某个拓扑序。
令 \(\mathrm{son}(u)\) 表示 \(u\) 的儿子构成的集合, \(f(u)\) 表示 \(u\) 的子树的拓扑序个数,那么方案数相当于将后 \(\mathrm{size}(u) - 1\) 个位置划分到 \(u\) 的每个儿子中的方案数,有转移
不妨令根为 \(1\),将上面的表达式展开,得到总拓扑序个数为
推论:\(n\) 个点的外向森林的拓扑序个数也为 \(\frac{n!}{\prod_{i = 1}^n \mathrm{size}(u)}\),因为新建一个超级源点连向每棵树的根后,整个森林就变成了一棵外向树。
2. 洛谷 P4099 [HEOI2013] SAO
原题链接:https://www.luogu.com.cn/problem/P4099
方法 1:直接上 DP,设 \(f(u, i)\) 表示 \(u\) 的子树中满足 \(u\) 排在第 \(i\) 位的拓扑序个数。转移相当于树形背包,时间复杂度为 \(\Theta(n^3)\),使用前缀和优化即可做到 \(\Theta(n^2)\)。
方法 2:我们只会算所有边都是外向边的树的拓扑序个数,但这道题中,边既有外向边又有内向边。因此考虑对所有内向边做二项式反演,设原树有 \(m\) 条内向边,我们钦定其中 \(k\) 条边为外向边、剩余 \(m - k\) 条边的方向随意。那么一种这样的方案的贡献即为断掉这 \(m - k\) 条边形成的外向森林的拓扑序个数,乘上容斥系数 \((-1)^k\)。
根据外向森林的拓扑序计数公式,我们只需要算出每种方案的 \(\frac{(-1)^k}{\prod_{i = 1}^n \mathrm{size}(u)}\) 之和即可,其中 \(\mathrm{size}(u)\) 表示断掉 \(m - k\) 条边后 \(u\) 子树的大小。考虑 DP,设 \(f(u, i)\) 表示只考虑 \(u\) 的子树,满足断边后 \(u\) 所在子树大小为 \(i\),的所有断边方案的贡献之和。转移相当于属性背包,无需优化即可做到 \(\Theta(n^2)\) 的时间复杂度。
3. 期望的线性性
(1) 对于随机变量 \(X\) 和常数 \(k\),有 \(E(kx) = k \cdot E(X)\)。
(2) 对于两个不一定相互独立的随机变量 \(X, Y\),有 \(E(X + Y) = E(X) + E(Y)\)。
(3) 对于两个相互独立的随机变量 \(X, Y\),有 \(E(XY) = E(X) \cdot E(Y)\)。
证明:对于 (1),有
对于 (2),有
对于 (3),根据 \(X, Y\) 的独立性,有 \(P(X = x \wedge Y = y) = P(X = x) P(Y = y)\),因此
4. 洛谷 U216322 石子问题
原题链接:https://www.luogu.com.cn/problem/U216322
设随机变量 \(t_i\) 表示“第 \(i\) 堆石子在第几轮被选中”,随机变量 \(x_i = [t_i \leq t_1]\),根据期望的线性性,答案即为 \(E(\sum_i x_i) = \sum_i E(x_i) = \sum_i P(t_i \leq t_1)\)。
显然 \(P(t_1 \leq t_1) = 1\)。对于 \(i > 1\),考虑第一次抽中第 \(i\) 堆石子和第 \(1\) 堆石子之一的时刻,此时抽中两堆石子的概率比为 \(a_i : a_1\),因此 \(P(t_i \leq t_1) = \frac{a_i}{a_i + a_1}\)。时间复杂度为 \(\Theta(n \log n)\)。
5. CF280C Game on Tree
原题链接:https://www.luogu.com.cn/problem/CF280C
题目等价于如下过程:随机一个 \(1 \sim n\) 的排列 \(p\),按 \(p\) 的顺序依次枚举每个点 \(u\),如果 \(u\) 还没有被删除则操作一次点 \(u\),将 \(u\) 子树内的点全删掉,否则不执行任何操作。最终求操作次数的期望值。
根据期望的线性性,答案等价于每个点被操作的概率之和。而一个点 \(u\) 被操作当且仅当它在 \(p\) 中出现的位置比它的祖先更靠前。也就是说,记 \(u\) 的祖先(包括 \(u\) 自己)构成的集合为 \(S(u)\),而将 \(p\) 中所有属于 \(S(u)\) 的元素拉出来构成的子序列为 \(q(u)\),那么 \(u\) 被操作当且仅当 \(u\) 是 \(q(u)\) 的第一个元素。而我们知道 \(q(u)\) 为 \(S(u)\) 的任何一个排列的概率都相等,因此 \(u\) 在 \(q(u)\) 中任何一个位置出现的概率都相等,因此 \(u\) 为 \(q(u)\) 第一个元素的概率即为 \(u\) 深度的倒数 \(\frac{1}{\mathrm{dep}(u)}\)。
答案即为每个点深度的倒数之和,时间复杂度为 \(\Theta(n)\)。
6. Gym102978H Harsh Comments
原题链接:https://codeforces.com/gym/102978/problem/H
令随机变量 \(x_i\) 表示评论 \(a_i\) 被删除的时间,随机变量 \(y_i\) 表示评论 \(b_i\) 被删除的时间,那么答案即为 \(E(n + \sum_{i = 1}^m [b_i \leq \max_{k = 1}^n a_k])\)。根据期望的线性性,答案为 \(n + \sum_{i = 1}^n P(b_i \leq \max_{k = 1}^n a_k)\)。因此我们不妨对每个 \(b_i\) 分别考虑,问题转化为只含有 \(a_1, a_2, \cdots, a_n, b_i\) 这些评论的子问题。然后我们发现所求概率的含义为“存在 \(a_k\) 比 \(b_i\) 大的概率”,而通常情况下“存在”并不如“任意”好求,因此考虑容斥,将“存在 \(a_k\) 比 \(b_i\) 大的概率”转化为 “任意 \(a_k\) 都比 \(b_i\) 小的概率”,即我们只需要求 \(b_i\) 在所有 \(a_i\) 后面被删除的概率即可。
令 \(s_i = b_i + \sum_{k = 1}^n a_k\)。考虑一组满足要求的删除顺序 \(a_{p_1}, a_{p_2}, \cdots, a_{p_n}, b_i\),出现这种顺序的概率为 \(\frac{a_{p_1}}{s_i} \cdot \frac{a_{p_2}}{s_i - a_{p_1}} \cdot \frac{a_{p_3}}{s_i - a_{p_1} - a_{p_2}} \cdot \cdots \cdot \frac{a_{p_n}}{a_{p_n} + b_i}\),我们发现这个值与删除的顺序有关。因此如果直接根据这个式子 DP,那么我们需要不可避免地记录每个 \(a_k\) 是否被选,而这样做复杂度至少是 \(\Theta(2^n)\) 的,显然不可接受。
那么我们该怎么办呢?我们发现问题出在分母上,也就是说每次随机的范围不一样。考虑通过一种方式将它们变得一样————每次我们仍然在这 \(n + 1\) 条评论中随机,只是如果随机到被删除的评论我们就不管它,只有随机到还没有被删除的评论才把它删掉,不停地这样随即下去直到永远。(同时 \(x_k, y_i\) 的含义也相应地发生改变。)这样问题就变得好做多了————此时我们需要求所有 \(x_k\) 都小于 \(y_i\) 的概率,但我们发现求“钦定若干 \(x_k\) 大于 \(y_i\),其余没有限制”的概率要好求得多,因为这个条件相当于在时刻 \(y_i\) 之前,每一次随机的范围都必须落在没有被钦定的评论中。即令没有被钦定的评论的 \(a_k\) 之和为 \(t\),枚举每个 \(y_i\) 的可能值值,即可得到这个概率为
直接考虑二项式反演,预处理所有“未被钦定的 \(a_k\) 之和为 \(t\) 的方案”的容斥系数之和即可,而这个预处理可以使用背包完成。令 \(V = \sum_{i = 1}^n a_i\),\(P = 998244353\),时间复杂度即为 \(\Theta(nV + mV \log P)\),可以通过。
双倍经验:洛谷 P5644 [PKUWC2018] 猎人杀,注意这道题直接背包是过不去的,需要使用生成函数 + 分治 NTT 优化。
2025.6.16
1. CF235D Graph Game
原题链接:https://www.luogu.com.cn/problem/CF235D
首先,原题等价于等概率随机一个排列 \(p\),按 \(p\) 中的顺序依次枚举每个点,遍历该点所在的连通块并删掉该点。不难发现这个过程与原题是等价的:对于任意时刻所形成的连通块,该连通块之后必然会再次分裂,且删掉其中任意一个点的概率仍然是相等的。
接下来我们考虑树的情况。根据期望的线性性,原题等价于对每个有序点对 \((u, v)\),删除点 \(u\) 前 \(u, v\) 在同一连通块的概率之和。而这个概率相当于 \(u\) 是 \(u\) 到 \(v\) 的简单路径上所有点中(包括端点)最先被删掉的点的概率。令该路径的点数为 \(d(u, v)\),我们知道对于每个由该路径上的所有点构成的排列 \(q\),\(q\) 作为 \(p\) 的子序列出现的概率都是相等的,因此 \(p\) 是第一个被删掉的概率即为 \(\frac{1}{d(u, v)}\)。
最后再考虑基环树的情况。如果 \(u, v\) 间简单路径不经过环那么概率还是一样,否则 \(u, v\) 间就会有两条路径,而我们要求的是存在一条路径在 \(u\) 被删的前一刻仍然连通的概率。考虑容斥,答案即为“第一条路径连通的概率 + 第二条路径连通的概率 - 两条路径都连通的概率”,即若记这两条路径的点数分别为 \(d_1, d_2\),总点数(公共点只算一次)为 \(d_3\),答案即为 \(\frac{1}{d_1} + \frac{1}{d_2} - \frac{1}{d_3}\)。
枚举每个有序点对求和即可,时间复杂度为 \(\Theta(n^2)\)。
2. LOJ #6240. 仙人掌
题意和上一题大致相同,区别在于把“基环树”换成了“边仙人掌”。
建出圆方树,那么一个方点有两种含义:一条包含两个点的边,或者一个包含至少三个点的环。对于第一种情况经过方点的路径是唯一的,对于第二种情况则有两条。而我们需要对每个有序点对 \((u, v)\),求删去点 \(u\) 前 \(u, v\) 间至少存在一条连通的简单路径的概率。
依旧考虑容斥,对每个第二类方点钦定“第一条简单路径连通”、“第二条简单路径连通”或“两条简单路径都联通”,第三种情况需要带一个 \(-1\) 的容斥系数。然后使用一个体积为路径总点数的背包,将每个方点的钦定方法拼起来即可。时间复杂度为 \(\Theta(n^3)\)。
3. 置换环数与排列逆序对数在奇偶性上的关系
感觉比较厉害。遇到这种逆序对数奇偶性相关的问题,我们应该考虑调整法,而不是通常情况下的配对法。
对一个长度为 \(n\) 的排列 \(a\),考虑交换两个元素 \(a_i, a_j (i < j)\) 会造成什么影响。考虑相对大小关系发生变化的元素对一定形如 \((a_k, a_i)\)、\((a_k, a_j)\) 或 \((a_i, a_j)\),而对于任意位置 \(k (k \neq i, k \neq j)\),\((a_k, a_i), (a_k, a_j)\) 的相对大小关系要么都发生变化,要么都不发生变化,并且 \((a_i, a_j)\) 的相对大小关系一定发生变化。也就是说,任意交换两个元素,排列逆序对数的奇偶性一定会发生变化。而对于置换环,如果 \(a_i, a_j\) 同属于一个置换环,那么这个置换环分裂,否则它们所属的两个置换环合并。因此只要交换两个元素,置换环数的奇偶性与逆序对数的奇偶性都会发生变化。
考虑 \(a_i = i\) 时,逆序对数为 \(0\),置换环数为 \(n\)。因此当 \(n\) 为偶数时两者奇偶性相同,当 \(n\) 为奇数时两者奇偶性相反。特殊地,当整个排列构成一个大置换环时,逆序对数的奇偶性一定与 \(n\) 的奇偶性相反。
4. 矩阵树定理
下面我们默认图的点数为 \(n\),且图没有自环。实际应用的过程中,由于自环一定不会出现在生成树中,因此将图中所有自环删去答案不变。
(1) 有向图以 \(1\) 为根的内向生成树个数
内向树的特点是非根结点的唯一出边指向它的父亲,考虑对着这个计数。具体而言,设点 \(i\) 的出度为 \(\mathrm{out}(i)\),那么对于 \(i > 1\),我们有 \(\mathrm{out}(i)\) 种钦定它父亲的办法,因此总方案数为 \(\prod_{i = 2}^n \mathrm{out}(i)\)。这么计数显然会算重,因为可能出现环,具体而言,我们得到的是一棵以 \(1\) 为根的内向树,和若干棵(可能为零棵)内向基环树。因此考虑经典容斥模型,我们钦定其中出现 \(k\) 个环以及这 \(k\) 个环是什么,剩下没有被钦定的点随意连出边,带上容斥系数 \((-1)^k\)。这样求出的方案数就是正确的。
而我们惊奇地发现钦定的方案与 \(2 \sim n\) 的排列是一一对应的。具体而言,如果一个点 \(u\) 被钦定在了某个环中,那么它的出边一定不会指向它自己,因此我们构造一个序列 \(a\),满足如果点 \(u\) 被钦定在了某个环中,那么 \(a_u\) 的值即为 \(u\) 的出边指向的点,否则 \(a_u = u\)。容易发现这样构成的 \(a\) 序列一定是一个排列,且每个排列都可以唯一地还原出一组钦定方案。那么不妨将求每组钦定方案的方案数(乘容斥系数)之和转化为求每个排列的贡献之和,且根据钦定的方案可以得到排列 \(a\) 的贡献的求法:构建权值序列 \(b_i\),对于 \(i > 1\),如果 \(a_i = i\) 那么 \(b_i = \mathrm{out}(i)\),否则 \(b_i\) 即为从 \(i\) 指向 \(a_i\) 的边的数量。令 \(k\) 表示所有满足 \(a_i \neq i\) 的元素构成的置换环数量,那么排列 \(a\) 的贡献即为 \((-1)^k \prod_{i = 2}^n b_i\)。
现在我们有排列 \(a\),\(a\) 中每个元素取每种值时对应的贡献,以及对应的是带上容斥系数 \((-1)^k\) 的积和式。我们发现这个东西长得非常像行列式,唯一的区别在于行列式的系数是 \(-1\) 的逆序对数次方,而我们要求的式子的系数是 \(-1\) 的“非平凡”置换环数次方(这里的“非平凡”指长度大于 \(1\))。而我们又知道这两者之间是存在某种关系的,具体而言,令 \(k\) 为“非平凡”置换环数,\(s\) 为满足 \(a_i = i\) 的元素数量,那么逆序对数的奇偶性即为 \(k \oplus s \oplus n\) 的奇偶性,即我们希望系数由 \((-1)^k\) 变成 \((-1)^{k + s - n}\)。因此我们需要在 \(b\) 序列中补上少掉的 \(n - s\) 个 \(-1\),即把每个满足 \(a_i \neq i\) 的元素的贡献 \(b_i\) 都乘上 \(-1\),这样这个式子就与行列式的式子一摸一样了。
此时问题就解决了:构造 \(n \times n\) 的矩阵 \(A_{i, j}\),若 \(i = j\) 那么 \(A_{i, j}\) 等于点 \(i\) 的出度 \(\mathrm{out}(i)\),否则等于有向边 \(i \rightarrow j\) 的数量的相反数。那么“以 \(1\) 为根的内向生成树个数”即为“\(A\) 去掉第 \(1\) 行第 \(1\) 列后的行列式值”;同理,“以 \(u\) 为根的内向生成树个数”即为“\(A\) 去掉第 \(u\) 行第 \(u\) 列后的行列式值”。矩阵 \(A\) 又称为基尔霍夫矩阵。
(2) 有向图以 \(1\) 为根的外向生成树个数
将所有边反向后问题,就变成了求内向生成树个数。因此仍然构造 \(n \times n\) 的基尔霍夫矩阵 \(A_{i, j}\),若 \(i = j\) 那么 \(A_{i, j}\) 等于点 \(i\) 的入度 \(\mathrm{in}(i)\),否则等于有向边 \(j \rightarrow i\) 的数量的相反数。那么“以 \(u\) 为根的外向生成树个数”即为“\(A\) 去掉第 \(u\) 行第 \(u\) 列后的行列式值”。
(3) 无向图的生成树个数
将每条无向边变成正反两条有向边后,问题就变成了求内向生成树个数。因此仍然构造 \(n \times n\) 的基尔霍夫矩阵 \(A_{i, j}\),若 \(i = j\) 那么 \(A_{i, j}\) 等于点 \(i\) 的度数 \(\mathrm{deg}(i)\),否则等于 \(i, j\) 间的无向边数量的相反数。那么“以 \(u\) 为根的生成树个数”即为“\(A\) 去掉第 \(u\) 行第 \(u\) 列后的行列式值”;特别地,由于以任意点为根都能得到相同的生成树集合,因此删去任意标号相同的行列后,所得矩阵的行列式值都相等。
模板题:洛谷 P6178 【模板】Matrix-Tree 定理,此题边带权,但若将边权视作重边数量则仍可使用矩阵树定理。时间复杂度为 \(\Theta(n^3)\)。
5. 洛谷 P4111 [HEOI2015] 小 Z 的房间
原题链接:https://www.luogu.com.cn/problem/P4111
将房间视为点,将相邻房间的墙视为无向边,那么所求即为无向图的生成树个数。直接使用矩阵树定理即可。需要注意的是此题模数为 \(V = 10^9\),因此对每一行 \(i\),在求行列式的值时,不能直接使用倍乘操作将 \(a_{i, i}\) 变成 \(1\),因为可能不存在 \(a_{i, i}\) 的逆元。正确做法是使用辗转相除法将其他行的 \(a_{j, i}\) 变为 \(0\),时间复杂度为 \(\Theta(n^3 + n^2 \log V)\)。
2025.6.17
1. 洛谷 P4336 [SHOI2016] 黑暗前的幻想乡
原题链接:https://www.luogu.com.cn/problem/P4336
钦定若干公司必须出现是困难的,但钦定若干公司必须不出现是简单的,此时我们只需要将没有被钦定的公司能够负责的边建成一张图,答案即为该无向图的生成树个数。容斥后使用矩阵树定理即可。时间复杂度为 \(\Theta(2^n n^3)\),但常数极小,可以通过。
2. 洛谷 P3317 [SDOI2014] 重建
原题链接:https://www.luogu.com.cn/problem/P3317
对于一棵特定的生成树 \(T\),它出现的概率为“树边都出现的概率”乘上“非树边都不出现的概率”,即 \(\big( \prod_{(u, v) \in T} p(u, v) \big) \big( \prod_{(u, v) \notin T} (1 - p(u, v)) \big)\),写成只有树边贡献的形式即 \(\big( \prod_{(u, v)} (1 - p(u, v)) \big) \big( \prod_{(u, v) \in T} \frac{p(u, v)}{1 - p(u, v)} \big)\)。前面的括号是个常数,后面的括号代表每条树边的贡献,直接使用矩阵树定理算出后面的括号之和即可。时间复杂度为 \(\Theta(n^3)\)。
这里有个问题是当 \(p(u, v) = 1\) 时分母为 \(0\),此时无法使用上面那个式子计算。注意到满足 \(p(u, v) = 1\) 的边一定会出现在生成树上,因此我们先将这些边连出的连通块缩点,特判掉连通块有环的情况。此时连通块内部的非树边一定不能出现,因此要将概率乘上 \(1 - p(u, v)\),再对连通块之间的边使用矩阵树定理即可。
2025.6.18
1. 洛谷 P6624 [省选联考 2020 A 卷] 作业题
原题链接:https://www.luogu.com.cn/problem/P6624
考虑用欧拉反演将 \(\gcd\) 去掉,枚举生成树 \(T\),答案可表示为
因此我们只需要对每个 \(x\) 求出,在只保留边权为 \(x\) 倍数的边形成的子图 \(G_x\) 中,所有生成树的边权和之和即可。考虑对于一个特定的 \(x\) 如何求解,与生成树有关的值容易使我们想到矩阵树定理,但普通的矩阵树定理求的是所有生成树的边权乘积之和,因此这里并不能直接使用矩阵树定理求解。
一种比较暴力的思路是将生成树的贡献拆到每条边的贡献,这样一条边的贡献即为“求包含该边的生成树个数”乘上“这条边的权值”,每条边的和即为答案,而“包含该边的生成树个数”又可以容斥成“总生成树个数”减去“删掉该边的图的生成树个数”。因此我们不仅需要对每个 \(G_x\) 用一遍矩阵树定理,还需要对每个 \(G_x\) 所包含的每条边都用一遍矩阵树定理。令 \(V\) 为边权最大值,乍一看复杂度为 \(\Theta(m^2 n^3 V)\) 不可接受,但一条边权为 \(t\) 边其实只会被 \(d(t)\) 个图包含,因此时间复杂度其实是 \(\Theta(n^3 V + n^3 m \max d(t))\)。根据 这张表 两项差不多同阶,实际上可以通过。
上面的做法能通过只是因为该题复杂度均摊的特殊性质,我们还需要寻求对于单次询问,快速求出所有生成树的边权和的方法。这里有一种很神奇的做法:若将每条边的边权 \(w\) 修改为一次多项式 \(wx + 1\),那么对于一棵生成树,原来的边权和即为现在边权乘积的一次项系数。因此我们只需要维护出此时行列式在模 \(x^2\) 意义下的值即可。事实上可以证明对于 \(b \neq 0\) 的多项式 \(ax + b\),其在模 \(n^2\) 意义下有唯一的乘法逆元 \(-\frac{a}{b^2}x + \frac{1}{b}\)(解个方程就行了),此时模 \(x^2\) 意义下多项式的四则运算都是良定义的,我们仍然可以使用高斯消元法求出行列式的值。时间复杂度为 \(\Theta(n^3 V)\)。
这里有个问题,就是当行列式中存在形如 \(ax (a > 0)\) 的多项式时,除法就不是良定义的,比如在模 \(x^2\) 意义下的除法 \(6x \div x\),模之前的多项式既可能是 \(6x \div x = 6\),又可能是 \((2x^2 + 6x) \div x = 2x + 6\)。此时无法在模 \(x^2\) 意义下求解,必须求出原本的多项式才行。但事实上观察本题的边权 \(wx + 1\),我们会发现常数项为 \(0\) 代表这两个点之间根本没有边,此时一次项也必然为 \(0\),因此根本不会出现上述情况,放心使用高斯消元求行列式即可。
2. 洛谷 P4208 [JSOI2008] 最小生成树计数
原题链接:https://www.luogu.com.cn/problem/P4208
令 \(T\) 为 \(G\) 的某棵生成树,\(G_{\leq x}\) 表示删去 \(G\) 中边权大于 \(x\) 的边得到的新图。观察 Kruskal 算法的流程可知,\(T\) 是 \(G\) 的最小生成树当且仅当对任意边权 \(x\),\(T_{\leq x}\) 和 \(G_{\leq x}\) 中点的连通性相同(即对任意点对 \(u, v\),\(u, v\) 在 \(T_{\leq x}\) 中连通当且仅当 \(u, v\) 在 \(T_{\leq x}\) 中连通)。
先将边权离散化,记离散化后最大的边权为 \(p\)。枚举边权 \(x \in [1, p]\),将 \(G_{\leq x - 1}\) 中的连通块缩点,并在它们之间连上边权为 \(x\) 的边,得到的新图 \(G'\) 即可表示在 \(G_{\leq x}\) 中哪些连通块会合并。我们的任务即为对 \(G'\) 中每个连通块都求出一棵任意生成树,使得 \(T_{\leq x - 1}\) 中对应的连通块也合并成 \(T_{\leq x}\)。因此对每个连通块都使用矩阵树定理,然后用乘法原理将答案合并即可。注意特判掉原图 \(G\) 不连通的情况,因为这样我们求出来的是原图的生成森林数量,原图根本就没有生成树。
关于时间复杂度:设变量 \(c\) 为任意一个 \(G'\) 中任意连通块的大小,求生成树的总复杂度即为 \(\Theta(\sum c^3)\)。而我们知道 \(G'\) 中的一个大小为 \(c\) 的连通块相当于生成树上增加 \(c - 1\) 条边,因此 \(\sum (c - 1) = n - 1\)。如果抛开大小为 \(1\) 的连通块,即保证每一次合并都会新增至少一条边,那么有 \(\sum c \leq 2n\),\(\sum c^3 \leq {c_{max}}^2 \sum c \leq 2n^3\),此时计算生成树个数的时间复杂度为 \(\Theta(n^3)\)。其余部分只要实现得稍微精细一点就没有太大问题。
2025.6.19
QOJ #7408. Determination
原题链接:https://qoj.ac/problem/7408
考虑将行列式按定义拆开。对于一个排列 \(f\),规定当 \(f_i = i\) 时位置 \(i\) 的贡献为 \(d_i\),当 \(f_i = p_i\) 时位置 \(i\) 的贡献为 \(a_b\),当 \(f_{p_i} = i\) 时位置 \(p_i\) 的贡献为 \(a_i\),其余位置贡献为 \(x\)。定义该排列 \(f\) 的权值为所有位置的贡献的乘积,求“有偶数个逆序对的 \(f\) 的权值和”减去“有奇数个逆序对的 \(f\) 的权值和”。
注意到题目中有个特殊条件 \(1 \leq p_{i + 1} \leq i\),这相当于所有位置构成一棵 \(n\) 个点的树,且 \(i\) 的父亲为 \(p_i\)。称 \(f_i = x\) 为“\(i\) 指向 \(x\)”。
当 \(x = 0\) 时,要使排列贡献不为 \(0\),那么 \(i\) 只能指向 \(i\) 自己或者与 \(i\) 相邻的点。此时这棵树满足如下两个性质:
- 在 \(i\) 子树中的所有点中,只有 \(i\) 可能指向子树外。
- 在 \(i\) 的所有儿子中,至多只有一个儿子指向 \(i\)。如果存在这样的儿子 \(u\),那么 \(u\) 的子树中存在恰好一个点 \(v\) 满足子树内没有点指向 \(v\)。如果 \(v \neq u\),那么 \(u\) 子树外的所有点也不可能指向 \(v\),这与 \(f\) 是排列矛盾。因此 \(v = u\),即此时 \(u\) 子树内有且仅有 \(u\) 一个点满足没有点指向它。
因此如果存在儿子 \(u\) 满足 \(f_u = i\),那么必有 \(f_i = u\),否则 \(i\) 可以选择指向它自己或父亲 \(p_i\)。这说明排列 \(f\) 形成的置换环长度至多为 \(2\),即一个点或一条树边,直接使用树形 DP 统计方案数即可。
当 \(x \neq 0\) 时,\(i\) 指向 \(f_i\) 的边可能为非树边(非树边贡献为 \(x\)),此时不能直接用上面的做法。考虑将行列式的每个元素都写成 \(x + g_{i, j}\) 的形式,并将其看作关于 \(x\) 的一次多项式,那么有个惊人的结论:该行列式的值也是一次多项式,所有高于一次的项的系数均为 \(0\)。
考虑证明这一结论。将行列式每一项的 \(n\) 个括号拆开,记一种“拆法”为对每个 \(k\),规定“从第 \(k\) 个括号里拆出一次项 \(x\) 还是常数项 \(g_{i, j}\)”。考虑对于每种次数至少为 \(2\) 的拆法,记其前两个 \(x\) 分别来自第 \(p, q\) 个括号,那么对于一个排列 \(f\),交换第 \(p, q\) 可以得到与之配对的排列 \(f'\),这样可以将排列两两配对,且每一对排列的权值相同、逆序对数奇偶性恰好相反。因此每一对排列的贡献可以互相抵消,这一种拆法的贡献为 \(0\)。因此所有高于一次的项的系数均为 \(0\)。
那么我们只需要求出一次项系数和常数项即可。常数项和上面的树形 DP 本次相同;一次项系数即可将恰好一个 \(f_i\) 的贡献替换为 \(x\),即至多只有一个置换环的长度不为 \(2\),因此仍然可以采用类似的树形 DP 解决。转移的时候注意带上 \(-1\) 的置换环数(逆序对数)次方。时间复杂度为 \(\Theta(n)\)。