2024.10 做题记录

1.2024 代码源 CSP-S 模拟 Day7

solution

2.2024 代码源 CSP-S 模拟 Day8

solution

3.2024 代码源 CSP-S 模拟 Day9

solution

4.2024 代码源 CSP-S 模拟 Day10

solution

5.2024 代码源 CSP-S 模拟 Day11

solution

6.2024 代码源 CSP-S 模拟 Day12

solution

7.2024 正睿 CSP 七连测 Day5

solution

8.F - Permutation Oddness

先把绝对值的贡献拆掉:

\[\lvert p_i - i \vert = \begin{cases} p_i - i, \text{ if } i \le p_i \\ i - p_i, \text{ otherwise} \end{cases} \]

所以考虑从 \(1 \rightarrow n\) 分别考虑每个位置填什么数、每个数填到什么位置。

直接 DP,发现我们只关心每个位置填的数是之前填过的还是没填过的,每个数填的位置是之前考虑过的还是没考虑过的。

所以记 \(f_{i, j, k}\) 表示考虑了 \(1 \sim i\),其中还有 \(j\) 个位置没填,怪异度为 \(k\) 时的方案数。

转移可以通过分类讨论得到:

\[\begin{aligned} f_{i, j, k} &\leftarrow f_{i - 1, j, k} \\ f_{i, j, k} &\leftarrow f_{i - 1, j, k} \cdot 2j \\ f_{i, j, k} &\leftarrow f_{i - 1, j - 1, k + 2i} \\ f_{i, j, k} &\leftarrow f_{i - 1, j + 1, k - 2i} \cdot (j + 1)^2 \\ \end{aligned} \]

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

9.P3736 [HAOI2016] 字符合并

首先最后一定会被缩成小于 \(k\) 个字符,因为缩一定是优的。

而且一个区间 \([l, r]\) 缩完之后的长度是固定的,为 \((r - l) \bmod (k - 1) + 1\)

然后 DP 状态就比较显然了:\(f_{l, r, S}\) 表示区间 \([l, r]\) 缩成了 \(S\) 的最大分数。

转移考虑把 \(S\) 的最后一个字符扔到右边,其余的扔到左边,注意在 \(S\) 中只有一个元素的时候要枚举 \(S\) 展开后的形态再划分。

时间复杂度 \(O(\frac{n^32^k}{k})\),跑不满。

10.P5336 [THUSC2016] 成绩单

显然是区间 DP。记 \(f_{l, r}\) 表示把 \([l, r]\) 全删掉的最小代价。

发现转移的时候需要把 \([l, r]\) 的若干个不交的子区间删掉来算答案,这个还可以区间 DP。

\(g_{l, r, i, j}\) 表示将 \([l, r]\) 删到值域是 \([l, r]\) 的子集的最小代价,转移为:

\[g_{l, r, i, j} \leftarrow \min\bigg(\min_{k \in [l, r)} \{ g_{l, k, i, j} + g_{k + 1, r, i, j} \}, f_{l, r}\bigg) \]

然后 \(f\) 的转移就是:

\[f_{l, r} \leftarrow \min_{i \le j} \{ g_{l, r, i, j} + (j - i)^2 \} \]

离散化后时间复杂度 \(O(n^5)\)

11.P3349 [ZJOI2016] 小星星

DP 是显然的:记 \(f_{u, i, S}\) 表示点 \(u\) 对应 \(i\)\(S\) 中的点已经被对应过的方案数。
转移为:

\[f_{u, i, S} \times f_{v, j, T} \rightarrow f'_{u, i, S \cup T}, \text{ if there exists edge }(i, j)\text{ and } S \cap T = \varnothing \]

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

发现转移形式是子集卷积,可以做到 \(O(n^4 2^n)\),不过不足以通过。

发现恰好为 \(S\) 是不好算的,考虑子集反演。

\(g(S)\) 表示钦定 \(S\) 外元素不选的方案数,\(f(S)\) 表示恰好选 \(S\) 中元素的方案数,那么有:

\[g(S) = \sum_{T \subseteq S} f(T) \]

根据子集反演,有:

\[f(S) = \sum_{T \subseteq S} (-1)^{\vert S \rvert - \lvert T \rvert} g(T) \]

所以我们只需算出钦定 \(S\) 外元素不选的方案数即可,这个可以 \(O(n^3)\) DP。

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

12.P4516 [JSOI2018] 潜入行动

简单题。记 \(f_{u, i, 0 / 1, 0 / 1}\) 表示点 \(u\) 为根的子树中,选了 \(i\) 个点,\(u\) 有没有被覆盖,\(u\) 有没有被选的方案数。

转移是树形背包,时间复杂度 \(O(nk)\)

13.P5281 [ZJOI2019] Minimax搜索

先发掘一下性质。先把每个点的权值 \(val_u\) 算出来,发现等于 \(W\) 的一定是一条根到叶子的链。

发现如果我们想让根节点的权值变化,那么一定会让这条链上的权值改变。

把这条链挖掉,这样树就分成了若干个小的子树,\(W\) 改变就必须有至少一个小的子树的改变影响到了链上的点。

至少一个不好算,考虑计算所有的小的子树都没影响到根链上的点的概率 \(p\),然后用 \(1 - p\) 乘总方案数 \(2^{leaf}\) 计算答案。

考虑 DP,对于链上的点,记 \(f_{u, i}\) 表示点 \(u\) 为根的子树中,修改的代价 \(\le i\)\(u\) 权值不变的概率,那么 \(p_i = \prod f_{u, i}\)

对于深度为奇数且父亲在链上的点,它的父亲取的是儿子中的最小值,如果要计算父亲权值不变的概率,我们要知道点 \(u\) 的权值 \(\ge W\) 的概率。

对于深度为偶数且父亲不在链上的点,它的父亲取的是儿子中的最大值,如果要计算父亲权值 \(\ge W\) 的概率,我们要知道点 \(u\) 的权值 \(\ge W\) 的概率。

其余的转移可以依次类推。

为了保持转移的一致性,对于奇数层的点,我们记 \(f_{u, i}\) 表示点 \(u\) 为根的子树中,修改的代价 \(\le i\)\(u\) 权值 \(< W\) 的概率;对于偶数层的点,我们记 \(f_{u, i}\) 表示点 \(u\) 为根的子树中,修改的代价 \(\le i\)\(u\) 权值 \(> W\) 的概率。这样我们的转移就是:

\[f_{u, i} \leftarrow \prod_{v \in \text{son}(u)} (1 - f_{v, i}) \]

这样我们就得到了 \(O(n^2)\) 的做法。

发现我们需要做的操作是全局取反、全局加一、把对应位置的 DP 值乘起来,所以直接线段树合并优化 DP 即可。

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

还有一种做法,就是发现当 \(i\) 变化的过程中,每个叶子结点的 DP 值至多会变化一次,所以可以写出转移矩阵,通过类似于 DDP 的方式维护。

注意这种方法需要求逆元,注意除 0 的情况。

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

14.E. Gosha is hunting

首先 DP 是显然的:记 \(f_{i, x, y}\) 表示考虑了前 \(i\) 个,第一类选了 \(x\) 个,第二类选了 \(y\) 个的最大期望。
转移为:

\[\begin{aligned} f_{i, x, y} &\leftarrow f_{i - 1, x, y} \\ f_{i, x, y} &\leftarrow f_{i - 1, x - 1, y} + p_i \\ f_{i, x, y} &\leftarrow f_{i - 1, x, y - 1} + q_i \\ f_{i, x, y} &\leftarrow f_{i - 1, x - 1, y - 1} + p_i + q_i - p_i \cdot q_i \end{aligned} \]

非常显然的一件事是如果记 \(F_{i, x}(y)\) 表示只考虑前 \(i\) 个,第一类选 \(x\) 个,第二类选 \(y\) 个的最大期望,那么 \(F_{i, x}(y)\) 是凸函数。

所以可以通过 WQS 二分优化到 \(O(n^2 \log \epsilon^{-1})\)

考虑继续优化,目标是优化 check 部分。

我们 check 部分做的事是计算选恰好 \(a\) 个第一类,每选一个第二类有 \(x\) 的代价时的最大期望。

对于第 \(i\) 个物品,分类讨论一下:

  • 同时选为第一类和第二类,贡献是 \(p_i + q_i - p_i \cdot q_i - x\)
  • 只选为第一类,贡献是 \(p_i\)
  • 只选为第二类,贡献是 \(q_i - x\)
  • 不选,贡献是 0。

考虑初始每个物品都不被选为第一类,能获得一个初始代价,然后贪心地选出变化量前 \(a\) 小的选为第一类,这步可以通过 nth_element 实现,这样就做到了 \(O(n)\) check。

时间复杂度 \(O(n \log \epsilon^{-1})\)

15.P2120 [ZJOI2007] 仓库建设

DP 式子是显然的:记 \(f_{i}\) 表示在 \(i\) 处建仓库的最小费用。
转移为:

\[\begin{aligned} &f_{i} \leftarrow f_{j} + \operatorname{cost} (j, i) \\ &\operatorname{cost}(l, r) = c_r + \sum_{i= l + 1}^{r} (x_r - x_i) \cdot p_i \end{aligned} \]

\(s1_i = \sum_{j \le i} p_i, s2_i = \sum_{j \le i} p_i \cdot x_i\),那么 \(\operatorname{cost}(l, r)\) 可以化简为:

\[\operatorname{cost}(l, r) = c_r + x_r \cdot (s1_r - s1_l) - (s2_r - s2_l) \]

然后有两个方向,一个是斜率优化,一个是决策单调性,应该是本质相同的。

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

16.P5468 [NOI2019] 回家路线

\(f_{i}\) 表示走到列车 \(i\) 的最小代价,不难写出转移:

\[f_i \leftarrow f_j + A(p_i - q_j)^2 +B(p_i - q_j) + C \]

显然是斜率优化:

\[\begin{aligned} f_i &= f_j + Ap_i^2 + Aq_j^2 - 2Ap_iq_j + Bp_i - Bq_j + C \\ f_j + Aq_j^2 - Bq_j &= f_i - Ap_i^2 - Bp_i - C + 2Ap_iq_j \end{aligned} \]

也就是说,对于一个决策 \(j\),把它看成点 \((q_j, f_j + Aq_j^2 - Bq_j)\)\(i\) 的转移就是用 \(k = 2Ap_i\) 的直线去切这个点集,要求截距 \(b = f_i - Ap_i^2 - Bp_i - C\) 最小,所以维护点集下凸壳即可。

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

17.C - Clamp Clamp Clamp

如果把 \(a_{2i + 1}\) 看成 \(l_{i + 1}\)\(a_{2i + 2}\) 看成 \(r_{i + 1}\),那么就转化成了有 \(n\) 个区间 \([l_i, r_i]\),初始有一个点 \(a_0\),要依次把 \(a_0\) 拖到每个区间里,\(f(a)\) 表示 \(a_0\) 最后的位置。

发现只有极长的交非空的后缀和这个后缀的上一个区间有用。

如果不存在(所有区间交不为空),那么一定有 \(f(a) = n\),此时的方案数为 \((2n + 1) (n!)^2\)

否则,不妨记这个后缀的长度为 \(m\),交为 \([l, r]\)

如果 \(r_{n - m} < l\),那么 \(f(a) = l\),否则一定有 \(l_{n - m} > r\)\(f(a) = r\)

不妨讨论 \(r_{n - m} < l\) 的情况,另一种情况是对称的。

先钦定交的左端点 \(l\) 和极长后缀 \(m\),算方案数可以先从 \(m\) 个区间里选出左端点 \(l\),再选出剩下的 \(k - 1\) 个区间的左端点 \(l_i < l\),然后选出 \(k\) 个区间的右端点 \(r_i > l\),接着选出 \(l_{n - m} < r_{n - m} < l\),最后剩下区间的 \(l_i, r_i\) 可以任选,结果是:

\[\begin{aligned} & m \cdot l^{\underline{m - 1}} \cdot (2n - l)^{\underline{m}} \cdot \binom{l + 1 - m}{2} \cdot \big(2(n - (m + 1)) +1 \big)! \cdot 2^{-(n - (m + 1))} \\ = \ & m \cdot l^{\underline{m - 1}} \cdot (2n - l)^{\underline{m}} \cdot \binom{l + 1 - m}{2} \cdot \big(2n - 2m - 1 \big)! \cdot 2^{- n + m + 1} \\ = \ & m \cdot 2^{- n +m} \frac{l! \cdot (2n - l) ! \cdot (l - m + 1)! \cdot (2n - 2m - 1)!}{(l - m +1)! (2n - l - m)! (l - m - 1)!} \\ = \ & m \cdot 2^{- n +m} \frac{l! \cdot (2n - l) ! \cdot (2n - 2m - 1)!}{(2n - l - m)! (l - m - 1)!} \\ = \ & m \cdot 2^{m - n} \binom{2n - 2m - 1}{l - m - 1} \cdot (2n - l)! \cdot l! \\ \end{aligned} \]

那么 \(f(a) = l\) 的答案为:

\[\begin{aligned} &\sum_{m = 1}^{n - 1}m \cdot 2^{m - n} \binom{2n - 2m - 1}{l - m - 1} \cdot (2n - l)! \cdot l! \\ = \ & l! \cdot (2n - l)! \cdot 2^{- n} \sum_{m = 1}^{n - 1} m \cdot 2^{m} \binom{2n - 2m - 1}{l - m - 1} \\ \end{aligned} \]

现在要算的是后面那个式子,不难发现要通过递推的方式。

经过若干次尝试后,我们选择按下面的式子定义 \(f_{x, y}(l)\)

\[\begin{aligned} f_{a, b}(l) = \sum_{m = 1}^{n - 1} m^a \cdot 2^{m} \binom{2n - 2m - b}{l - m - 1} \\ \end{aligned} \]

然后就能解出递推式。

先考虑 \(f_{1, 1}(l)\),有:

\[\begin{aligned} f_{1, 1}(l) &= \sum_{m = 1}^{n - 1} m \cdot 2^{m} \binom{2n - 2m - 1}{l - m - 1} \\ &= \sum_{m = 1}^{n - 1} m \cdot 2^m \bigg( \binom{2n - 2m - 2}{l - m - 1} + \binom{2n - 2m - 2}{l - m - 2} \bigg) \\ &= \sum_{m = 1}^{n - 1} m \cdot 2^m \cdot \binom{2n - 2m - 2}{l - m - 1} + \sum_{m = 1}^{n - 1} m \cdot 2^m \cdot \binom{2n - 2m - 2}{l - m - 2} \\ &= \sum_{m = 1}^{n - 1} m \cdot 2^m \cdot \binom{2n - 2(m + 1)}{(l + 1) - (m + 1) - 1} + \sum_{m = 1}^{n - 1} m \cdot 2^m \cdot \binom{2n - 2(m + 1)}{l - (m + 1) - 1} \\ &= \sum_{m - 1 = 1}^{n - 1} (m - 1) 2^{m - 1} \binom{2n - 2m}{(l + 1) - m - 1} + \sum_{m - 1 = 1}^{n - 1} (m - 1) 2^{m - 1} \binom{2n - 2m}{l - m - 1} \\ \end{aligned} \]

把两部分分别考虑。

先看第二部分:

\[\begin{aligned} &\sum_{m = 2}^{n} (m - 1) 2^{m - 1} \binom{2n - 2m}{l - m - 1} \\ = \ & 2^{-1} \sum_{m = 2}^n m \cdot 2^m \cdot \binom{2n - 2m}{l - m - 1} - 2^{-1} \sum_{m = 2}^n 2^m \binom{2n - 2m}{l - m - 1} \\ = \ &\frac{f_{1, 0}(l)}{2} - \binom{2n - 2}{l - 2} + 2^{-1 }\cdot n \cdot 2^n \binom{0}{l - n - 1} - \frac{f_{0, 0}(l)}{2} + \binom{2n - 2}{l - 2} - 2^{-1} \cdot 2^n \cdot \binom{0}{l - n - 1} \\ = \ &\frac{f_{1, 0}(l) - f_{0, 0}(l) + [l = n + 1] \cdot (n - 1) \cdot 2^n}{2} \end{aligned} \]

然后第一部分是类似的:

\[\begin{aligned} & \sum_{m = 2}^{n} (m - 1) 2^{m - 1} \binom{2n - 2m}{(l + 1) - m - 1} \\ = \ & \frac{f_{1, 0}(l + 1) - f_{0, 0}(l + 1)}{2} - n \cdot 2^n \binom{0}{l - n} + 2^n\binom{0}{l - n} \\ = \ &\frac{f_{1, 0}(l +1) - f_{0, 0}(l + 1) + [l = n] \cdot (n - 1) \cdot 2^n}{2} \end{aligned} \]

合起来可以得到:

\[\begin{aligned} f_{1, 0}(l + 1) - f_{0, 0}(l + 1) = &2f_{1, 1}(l) - f_{1, 0}(l) + f_{0, 0}(l) - [l = n + 1]\cdot (n - 1) \cdot 2^n - [l = n]\cdot (n - 1) \cdot 2^n\\ \end{aligned} \]

对于 \(f_{0, 0}(l + 1)\)

\[\begin{aligned} f_{0, 0}(l + 1) &= \sum_{m = 1}^{n - 1} 2^m \binom{2n - 2m}{(l + 1) - m - 1} \\ &= \sum_{m = 1}^{n - 1} 2^m \bigg( \binom{2n - 2m - 1}{(l + 1) - m - 1} + \binom{2n - 2m - 1}{l - m - 1} \bigg) \\ &= f_{0, 1}(l + 1) + f_{0, 1}(l) \\ \end{aligned} \]

整理得到:

\[\begin{aligned} f_{0, 0}(l + 1) - f_{0, 1}(l + 1) = f_{0, 1} (l) \end{aligned} \]

对于 \(f_{1, 0}(l + 1)\)

\[\begin{aligned} f_{1, 0}(l + 1) &= \sum_{m = 1}^{n - 1} m2^m \binom{2n - 2m}{(l + 1) - m - 1} \\ &= \sum_{m = 1}^{n - 1} m 2^m \bigg( \binom{2n - 2m - 1}{(l + 1) - m - 1} + \binom{2n - 2m - 1}{l - m - 1} \bigg) \\ &= f_{1, 1}(l + 1) + f_{1, 1}(l) \end{aligned} \]

整理得到:

\[\begin{aligned} f_{1, 0}(l + 1) - f_{1, 1}(l +1) = f_{1, 1}(l) \end{aligned} \]

对于 \(f_{0, 1}(l)\)

\[\begin{aligned} f_{0, 1}(l) &= \sum_{m = 1}^{n - 1} 2^m \binom{2n - 2m - 1}{l - m - 1} \\ &= \sum_{m = 1}^{n - 1} 2^m \bigg( \binom{2n - 2(m + 1)}{(l + 1) - (m + 1) - 1} + \binom{2n - 2(m + 1)}{l - (m + 1) - 1}\bigg) \\ &= \sum_{m = 1}^{n - 1} 2^m \binom{2n - 2(m + 1)}{(l + 1) - (m + 1) - 1} + \sum_{m = 1}^{n - 1} 2^m \binom{2n - 2(m + 1)}{l - (m + 1) - 1} \\ &= \sum_{m - 1 = 1}^{n - 1} 2^{m - 1} \binom{2n - 2m}{(l + 1) - m - 1} + \sum_{m - 1 = 1}^{n - 1} 2^{m - 1} \binom{2n - 2m}{l - m - 1} \\ &= 2^{-1} \sum_{m = 2}^n 2^m \binom{2n - 2m}{(l + 1) - m - 1} + 2^{-1}\sum_{m = 2}^n 2^m \binom{2n - 2m}{l - m - 1} \\ &= 2^{-1} \bigg( f_{0, 0}(l + 1) - 2\binom{2n - 2}{l - 1} + 2^n \binom{0}{l - n} + f_{0, 0}(l) - 2\binom{2n - 2}{l - 2} + 2^n\binom{0}{l - n- 1} \bigg) \\ &= \frac{f_{0, 0}(l + 1) + f_{0, 0}(l) + [l = n + 1] \cdot 2^n + [l = n] \cdot 2^n}{2} - \binom{2n - 2}{l - 1} - \binom{2n - 2}{l - 2} \\ &= \frac{f_{0, 0}(l + 1) + f_{0, 0}(l) + [l = n + 1] \cdot 2^n + [l = n] \cdot 2^n}{2} - \binom{2n - 1}{l - 1} \end{aligned} \]

整理得到:

\[\begin{aligned} f_{0, 0}(l + 1) = 2f_{0, 1}(l) + 2 \binom{2n - 1}{l - 1} - f_{0, 0}(l) - [l = n + 1] \cdot 2^n - [l = n] \cdot 2^n \end{aligned} \]

结合上面的推导,可以得到:

\[\begin{aligned} \begin{cases} f_{1, 0}(l + 1) - f_{0, 0}(l + 1) = 2f_{1, 1}(l) - f_{1, 0}(l) + f_{0, 0}(l) - [l = n + 1]\cdot (n - 1) \cdot 2^n - [l = n]\cdot (n - 1) \cdot 2^n\\ f_{0, 0}(l + 1) - f_{0, 1}(l + 1) = f_{0, 1} (l) \\ f_{1, 0}(l + 1) - f_{1, 1}(l +1) = f_{1, 1}(l) \\ f_{0, 0}(l + 1) = 2f_{0, 1}(l) + 2 \binom{2n - 1}{l - 1} - f_{0, 0}(l) - [l = n + 1] \cdot 2^n - [l = n] \cdot 2^n \\ \end{cases} \end{aligned} \]

最总可以得到递推式:

\[\begin{aligned} \begin{cases} f_{0, 0}(l + 1) = 2f_{0, 1}(l) + 2 \binom{2n - 1}{l - 1} - f_{0, 0}(l) - [l = n + 1] \cdot 2^n - [l = n] \cdot 2^n \\ f_{0, 1}(l + 1) = f_{0, 1}(l) + 2 \binom{2n - 1}{l - 1} - f_{0, 0}(l) - [l = n + 1] \cdot 2^n - [l = n] \cdot 2^n \\ f_{1, 0}(l + 1) = 2f_{0, 1}(l) + 2 \binom{2n - 1}{l - 1} + 2f_{1, 1}(l) - f_{1, 0}(l) - [l = n + 1]\cdot n \cdot 2^n - [l = n]\cdot n \cdot 2^n\\ f_{1, 1}(l + 1) = 2f_{0, 1}(l) + 2 \binom{2n - 1}{l - 1} + f_{1, 1}(l) - f_{1, 0}(l) - [l = n + 1]\cdot n \cdot 2^n - [l = n]\cdot n \cdot 2^n\\ \end{cases} \end{aligned} \]

按式子递推即可。

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

18.2024 代码源 CSP-S 模拟 Day13

solution

19.2024 代码源 CSP-S 模拟 Day14

solution

20.2024 代码源 CSP-S 模拟 Day15

solution

21.AtCoder Regular Contest 185

solution

22.2024 代码源 NOIP 讲课 Day1

Day1 图论杂题

23.2024 代码源 CSP-S 模拟 Day16

solution

24.2024 代码源 NOIP 讲课 Day2

Day2 DP 杂题

25.2024 正睿 CSP 七连测 Day6

solution

26.P7473 [NOI Online 2021 入门组] 重力球

建反图,然后 BFS 即可。

时间复杂度 \(O(q + (n +m)^2)\)

27.P7113 [NOIP2020] 排水系统

拓扑排序加高精。

28.2024 代码源 CSP-S 模拟 Day17

solution

29.F. Jumping Around

首先单调性是比较好发现的,就是如果小的 \(k\) 可行,那么大的 \(k\) 一定也可行,所以我们不妨求出从 \(s\) 到每个点的最小的 \(k\)

连边 \((i, j, \big \lvert \lvert a_i - a_j \rvert - d \big \rvert)\) 表示从 \(i\) 直接跳到 \(j\) 所需的最小的 \(k\),那么我们要做的就是求出这张图的 MST。

考虑 Boruvka,现在的问题是如何对当前的每个连通块寻找最优的出边。

将边权的内层绝对值拆开,得到:

\[\big \lvert \lvert a_i - a_j \rvert - d \big \rvert = \begin{cases} \lvert a_i - d - a_j \rvert, \text{ if } a_i \ge a_j \\ \lvert a_i + d - a_j \rvert, \text{ if } a_i < a_j \\ \end{cases} \]

所以我们只需找到 \(a_i + d\)\(a_{i} - d\) 的前驱后继即可,这个可以 two pointers。

求出 MST 后 DFS 一边即可。

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

30.P6765 [APIO2020] 交换城市

首先发现,无解当且仅当图是一条链。

考虑 Kruskal 重构树,在其基础上我们还需维护当前点代表的连通块是不是一条链,这个可以通过维护链的端点简单实现。

如果一条边连接了两个不同的连通块,那么我们新建一个点,两个连通块的代表点都向这个点连边;如果一条边改变了一个连通块是否是链,那么我们新建一个点,将这个连通块的代表点向这个点连边,并标记这个点不是链。

查询时,我们先找到 Kruskal 重构树上两点的 LCA,如果 LCA 代表的点是链,那么就向上找直到找到一个不是链是点,或报告无解;如果不是链,就输出点所代表的边权。

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

31.E - Two Currencies

简单题。

首先发现我们只要有 2450 个银币就能想去哪去哪了。

所以我们可以拆点,将 \(u\) 拆成 2450 个点,分别表示在 \(u\)\(i\) 枚银币的状态。

然后连边跑最短路即可。

时间复杂度 \(O(n^3 \log n)\)

32.P4366 [Code+#4] 最短路

要解决边数的问题,这个我们可以通过每次只改变二进制下的一位来解决。

时间复杂度 \(O((n \log n + m) \log n)\)

33.P7516 [省选联考 2021 A/B 卷] 图函数

先考虑怎么计算 \(h(G)\)

考虑对每对点 \((i, j) \ (i \le j)\) 计算贡献,发现如果 \((i, j)\) 会对答案产生贡献,那么一定存在 \(i \rightarrow j\)\(j \rightarrow i\) 的路径满足路径上点的编号 \(\ge i\)

那么如果我们要计算每个 \(G_i\) 的答案,我们只需算出 \(T_{i, j}\) 表示 \(i, j\) 之间满足上面的条件的路径边权最小值的最大值。

首先我们会简单的 \(O(n^3)\) Floyd 做法。

这显然很没前途,考虑换一个角度。

我们按编号从大到小加入所有的边,如果加入一条边 \(w\) 后,\(i \rightsquigarrow j\)\(j \rightsquigarrow i\),那么 \(T(i, j) = w\)

维护正图和反图。对于一条边 \(u \rightarrow v\),如果 \(u\) 可达且 \(v\) 不可达,则从 \(v\) 开始暴力 BFS,把经过的边标记成可达;若 \(v\) 可达,则忽略;若 \(u, v\) 均不可达,那么就往 \(v\) 的边集中加入这条边。

发现我们维护的是 01 变量,考虑用 bitset 除个 \(\omega\)

发现直接用 bitset 维护出边边集之类的就好了。

时间复杂度 \(O\big(\frac{n^3}{\omega}\big)\)

34.P4926 [1007] 倍杀测量者

首先有三种类型的限制:

\[\begin{aligned} &x_A \ge (k - T) x_B \\ &(k + T)x_A > x_B \\ &x_C = X \end{aligned} \]

我们可以两边取对数之后进行差分约束:

\[\begin{aligned} &\log x_A \ge \log x_B +\log (k - T) \\ &\log x_A > \log x_B - \log (k +T) \\ &\begin{cases} \log x_C \ge \log X + 0 \\ \log x_C \le \log X + 0 \\ \end{cases} \end{aligned} \]

35.D - Small Multiple

考虑一个数是怎么被生成的:初始为 1,每次可以选择 \(\times 10\)\(+ 1\)

所以我们在模 \(k\) 的意义下 \(i \stackrel{0}{\longrightarrow} i \times 10\)\(i \stackrel{1}\longrightarrow i + 1\),跑最短路即可。

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

36.F. Oppa Funcan Style Remastered

首先只有质因数有用,所以先把 \(k\) 质因数分解,这部分可以 Pollard Rho。

先分类讨论掉质因数个数 \(\le 2\) 的情况,然后有最小质因数 \(\le 10^5\)

\(f_i\) 表示在模最小质因数的意义下为 \(i\) 的能凑出的最小的数,这个可以同于最短路转移。

单次时间复杂度 \(O(k^{\frac{1}{3}}\omega(k))\)

37.2024 代码源 CSP-S 模拟 Day18

solution

38.2024 代码源 CSP-S 模拟 Day19

solution

39.C. C+K+S

先对两个图建 DFS 树,求出每个点的深度。

考虑对于这样连接两张图的两条边:

![[Pasted image 20241021193102.png]]

它要满足的要求是 \(dep_A - dep_D + dep_C - dep_B + 2 \equiv 0 \pmod k\)

由于我们所有的这样的边都会形成一个环,所以我们就是在要求 \(dep_A - dep_B\) 全相等、\(dep_C + dep_D\) 全相等。

从值域上考虑,我们开两个桶,分别维护 \(dep_A = x\)\(dep_B = x\) 的数量,发现要做的就是循环位移若干位之后两个桶完全相同。

这个可以将 B 复制一份后 KMP。

对于 \(C\)\(D\) 同理。

最后求出所有可能的位移长度按照上面的式子判断即可。

时间复杂度 \(O(n + m + k)\)

40.E2. String Coloring (hard version)

感觉挺有意思的一道题的

首先可以转化成 \(i\)\(j < i\)\(s_j \le s_i\) 的连边,表示颜色可以相同,那么答案就是最小链覆盖。

根据 dilworth 定理,可以转化为最大反链,所以答案是 LDS 的长度。

时间复杂度 \(O(n \lvert \Sigma \rvert)\)

41.F. Cities Excursions

首先发现,如果终点固定了,那么每个点走的路径都是唯一的,只能走向最小的能到达终点的点。

所以离线,对所有终点求答案即可。

时间复杂度 \(O(n^2 + q)\)

42.Counting Is Fun (Hard Version)

感觉不难。

先看判定,如果 \(i\) 位置被操作,那么 \(i - 1\)\(i + 1\) 中一定有一个也被操作,所以必要条件是 \(a_{i - 1} + a_{i + 1} \ge a_i\)(这里钦定 \(a_0 = a_{n +1} = 0\))。

判定已足够简洁,考虑把判定扔到状态里 DP。

首先 \(O(n^3)\) 的 DP 是简单的。

考虑容斥,钦定若干个位置满足 \(a_i > a_{i - 1} + a_{i + 1}\)

发现如果我们这么钦定之后,\(i\)\(i +1\) 两个位置不能同时满足条件。

\(f_{i, j}\) 表示 \(a_i = j\) 的带容斥系数的方案数,转移考虑下一个位置钦定还是不钦定:

\[\begin{aligned} f_{i, j} &\rightarrow f_{i + 1, k} \\ f_{i, j} &\rightarrow f_{i + 2, k}, \text{ if } k \le m - j \end{aligned} \]

发现第一个是全局加,第二个数前缀加,所以直接打 tag 维护即可。

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

43.P9140 [THUPC 2023 初赛] 背包

考虑按性价比贪心。

我们选出 \(\frac{c_i}{v_i}\) 最大的物品作为基准物品,记它的体积、价值分别为 \(m, w\)

那么对于一个物品 \(v_i, c_i\),如果它选了 \(\operatorname{lcm}(m, v_i)\) 个,那么一定可以将它替换为若干个基准物品。

考虑对于一组方案 \((V', C')\),当查询 \(V\) 的答案时,如果 \(V \equiv V' \pmod m\),那么它对答案的贡献是 \(\frac{V - V'}{m} \cdot w +C'\)

这其实就是在说如果我们想最大化答案,就要最大化 \(C' - \frac{V'}{m} \cdot w\)

我们不妨在 \(\bmod m\) 的意义下做背包,那么我们加入一个物品时的转移就是:

\[f_{j + v_i} \leftarrow f_{j} + c_i - \left\lfloor \frac{j + v_i}{m} \right\rfloor \cdot w \]

因为我们选取的是性价比最优的物品,所以图中是没有正环的,所以对于一组剩余系中的最优决策,我们最多转 \(\max v_i\) 圈,每圈会将体积变大 \(m\),所以最大体积是 \(O(\max v_i^2)\) 级别的,配合 \(V \ge 10^{11}\) 的限制即可保证正确性。

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

44.P9963 [THUPC 2024 初赛] 前缀和

感觉好厉害的题啊。

组合意义的做法:

考虑有 \(n\) 个随机变量 \(\{ X_n\}\)\(P(X = 1) = p, P(X = 0) = 1 - p\),那么 \(\{x_n\}\) 就和 \(\{X_n\}\) 中第一个 1 的位置等分布,前缀和就是 \(\{X_n\}\) 中第 \(i\) 个 1 的位置。

现在问题就相当于问 \([l, r]\) 中期望有多少个 1,这个显然是 \(p \cdot(r- l + 1)\)

代数推导的做法:

写出 \(x_i\) 的 PGF:

\[\sum_{i \ge 1} p (1 - p)^{i - 1} \cdot x^i = \frac{px}{1 - (1 - p) \cdot x} \]

前缀和之后 \(y_i\) 的 PGF:

\[\left(\frac{px}{px - x + 1} \right)^i \]

求和可得到整个数列的 PGF:

\[\begin{aligned} F(x) &= \sum_{i = 1}^n \left( \frac{px}{px - x + 1} \right)^i \\ &= \frac{1}{1 - \dfrac{px}{px - x + 1}} - 1 \\ &= \frac{px - x + 1}{1 - x} - 1 \\ &= \frac{px}{1 - x} \end{aligned} \]

做前缀和可得:

\[G(x) = \frac{F(x)}{1 - x} = \frac{px}{(1-x)^2} \]

那么答案为:

\[[x^r] G(x) - [x^{l - 1}] G(x) = p(r - l + 1) \]

45.P9968 [THUPC 2024 初赛] 二进制

首先发现,一次删除最删 \(O(\log n)\) 个位置。

也就是说,我们直接暴力维护就是 \(O(n \log^2 n)\) 的。

可以精细一点做到 \(O(n \log n)\)

具体来讲,我们从小到大枚举 \(i\),计算 \(i\) 的答案。

于此同时,我们不维护所有长度 \(\le 1 + \log n\) 的串,而是维护所有长度 \(= 1 + \log i\) 的串的出现位置。

由于 \(\log i\) 只会变化 \(O(\log n)\) 次,所以重构的复杂度为 \(O(n \log n)\)

删除考虑使用树状数组维护每个位置之前删了几个位置,由于每个位置只会被删一次,这部分时间复杂度为 \(O(n \log n)\)

删除的位置在维护的出现位置中的变化可以懒惰删除。

具体来说,我们可以在出现位置的 vector 中维护若干个二元组 \((pos, k)\) 表示在位置 \(pos\),这个数是加入还是删除,这样查询的时候开桶统计一下即可,删除的时候把附近的 \(O(\log n)\) 个位置的出现位置全部删除后插入新的。

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

46.P9965 [THUPC 2024 初赛] 转化

读错题了,我说怎么不会 /tuu

先考虑第一问。

不妨新增一个种类,叫无色球。称第一类操作为将特定颜色的球变成无色球。

首先,如果这个位置有球,那么把第二类操作全做完一定不劣,然后我们通过第一类操作将其转化成无色球。

如果这个位置没有球而且想要这个位置球最多,那么我们可以把无色球全拿过来,然后通过第二类操作复制完。

如果这个位置没有球且没有要求,我们可以拿一个无色球过来,通过第二类操作复制,然后通过第一类操作使无色球的个数增加。

这样我们就成功解决了第一问。

再考虑第二问。

首先我们把上面的除了“想要这个位置球最多的”的操作都做了一定是不会更劣的。

现在有用的位置只有若干个只剩下第二类操作的位置。

而这些位置能通过第二类操作产生的球的个数是固定的,所以排序后贪心即可。

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

47.2024 代码源 CSP-S 模拟 Day20

solution

48.李赛 2024.10.23

solution

49.P4171 [JSOI2010] 满汉全席

每种材料建两个点,分别表示是汉式还是满式,条件是或的形式,2-sat 即可。

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

50.CF587D Duff in Mafia

对于每个点的所有边,如果有一种颜色出现了超过 2 次,那么一定无解;如果有多于一种颜色出现了 2 次,那么一定无解;如果恰好有一种颜色出现了 2 次,那么其中一条边一定会被选;否则每条边都有可能被选,且恰好有一条边会被选。

那么我们判定可行性就可以通过 2-sat 解决。

对于最小化最大边权的要求,可以套一个二分解决。

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

51.CF51F Caterpillar

连通块之间的合并是简单的,只需要依次把链的端点连起来即可。

首先要缩边双,这样我们就只需要解决树的问题了。

考虑钦定链,这样链上最后能剩的点就是选若干个点使得不互为祖先后代。

所以我们会把叶子全选上,而且链一定是选直径。

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

52.P8456 「SWTR-8」地地铁铁

https://www.luogu.com.cn/article/uw6b44gp

53.AGC025E Walking on a Tree

感觉好牛啊。

首先考虑如果每条边都被覆盖了偶数次,那么我们可以直接路径端点连边,跑欧拉回路定向。

因为是欧拉回路,所以每条边被正着覆盖和反着覆盖的次数是一样的。

如果有的边被覆盖了奇数次,那么我们直接给他和父亲之间的边加一条路径,这样就能调整成每条边都覆盖偶数次的情况。

此时一条边被正向覆盖和反向覆盖的次数之差不超过 1,所以是对的。

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

54.P6268 [SHOI2002] 舞会

二分图染色,然后直接流。

55.P4251 [SCOI2015] 小凸玩矩阵

首先二分转判定,是否能选出 \(n - k + 1\)\(\le mid\) 的数。

这个可以流,如果 \(a_{i, j} \le mid\),那么就 \(i\)\(j\) 连流量为 \(1\) 的边。

56.CF1684G Euclid Guess

首先发现,如果没有 \(m\) 的限制,我们可以通过 \((3t_i, 2t_i)\) 的数对把所有的 \(t_i\) 都构造出来。

否则,我们的构造过程一定是形如 \((2t + k, t + k) \rightarrow (t + k, t) \rightarrow (t, k)\),要求是 \(3t > m,3k \le m\)

发现我们将数分成了两组,只有组间的数才能匹配。

考虑我们会将什么样的 \(t\)\(k\) 进行匹配。我们发现 \(\gcd(t, k)\) 一定会出现在最后的序列中,所以我们匹配 \(k = \gcd(t, k)\) 一定是最优的,也就是 \(k \mid t\)

所以连边然后流即可。

57.CF1592F1 Alice and Recoloring 1

首先发现二、三操作是没用的,因为可以用一操作代替。

所以只有一、四操作是有用的。

操作是矩形异或 1 的形式,所以我们做一个后缀差分,这样操作 1 就变成了单点改,操作 2 就变成了改四个单点。

发现操作 2 至多进行一次,因为你进行更多次的时候就会改变 \(a_{n, m}\) 的状态,你就不能以 3 的代价改 4 个点了,那就不如 1 操作了。

所以扫一遍即可。

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

58.CF1592F2 Alice and Recoloring 2

还是只有一、四操作是有用的,但是四操作不是只会进行一次了。

考虑代价为 2 给我们带来了什么。

首先我们可以忽略 \(a_{n, m}\) 的状态,因为这个最多会总共带来 1 的代价。

然后我们只要是一次操作可以使三个点的状态变对就能直接操作,同时由这个性质还和推出一行一列最多操作一次。

所以对于一个能操作的 \((x, y)\),我们连边 \((x, y + n, 1)\),然后跑最大匹配。

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

59.P2153 [SDOI2009] 晨跑

每个点最多经过一次可以拆点,然后是最小费用最大流板子。

60.P2057 [SHOI2007] 善意的投票 / [JLOI2010] 冠军调查

最小割套路题。

首先对每个小朋友建一个长度为 2 的链,如果切掉第一条边就表示 0,切掉第二条表示 1。

选一个数会有一定的代价,这个可以直接连边。

对于一对朋友,我们是要求如果切的不一样就连。

61.AGC038F Two Permutations

通过把 \(P\)\(Q\) 循环分解,我们可以发现,构造出的 \(A\)\(B\) 序列中,对于一个原来的循环,它要么不变,要么被拆成若干个自环。

考虑最小割建模,计算最少有多少个相等的位置。

\(S\)\(T\) 拉若干条长度为 2 的链,链和循环一一对应,链上切第一条边表示状态是被分成了若干个自环(0),且第二条表示状态是不变(1)。

分别对于每个位置考虑贡献,记 \(P_i\) 所在的循环为 \(p_i\)\(Q_i\) 所在的循环为 \(q_i\)

分类讨论一下:

  • \(P_i = i, Q_i = i\),那么一定有 1 的贡献。
  • \(P_i \neq i, Q_i = i\),此时有:若 \(p_i\) 的状态为 0,那么有 1 的贡献,否则贡献为 0。
  • \(P_i = i, Q_i \neq i\),此时有:若 \(q_i\) 的状态为 0,那么有 1 的贡献,否则贡献为 0。
  • \(P_i \neq i, Q_i \neq i, P_i \neq Q_i\),此时有:若 \(p_i, q_i\) 的状态都为 0,那么有 1 的贡献,否则贡献为 0。
  • \(P_i \neq i, Q_i \neq i, P_i = Q_i\),此时有:若 \(p_i, q_i\) 的状态相同,那么有 1 的贡献,否则贡献为 0。

发现对于后两个限制我们并不能通过最小割处理,但是因为是二分图,所以可以黑白染色,也就是说对于 \(Q\) 的限制我们翻转一下,这样就能最小割了。

因为是二分图,所以时间复杂度 \(O(n \sqrt n)\)

62.P5038 [SCOI2012] 奇怪的游戏

显然是要黑白染色的,记黑点个数为 \(B\),白点个数为 \(W\)

不难发现黑点的和 \(s_B\) 和白点的和 \(s_W\) 都是不变的。

\(\text{Case1: }B \neq W\)

此时有 \(W - B = 1\),且 \(s_W - s_B = x\) 为定值,不难发现这个值就是最后相同的那个数。

所以我们只需要 check 这个数是否合法即可。

考虑算出每个位置应该被操作的次数 \(c_{i, j}\),那么对于每个黑格子,如果操作过它,那么相邻的白格子一定会被波及到。

所以我们可以将黑格子看做左部点,白格子看做右部点,每个黑格子向源点连容量 \(c_{i, j}\) 的边,每个白格子向汇点连容量为 \(c_{i, j}\) 的边, 每个黑格子向相邻的白格子连容量为 \(+\infty\) 的边,如果满流就有解。

\(\text{Case2: }B = W\)

这种情况我们一定能通过 \(1\times 2\) 的矩形覆盖整个棋盘,这其实就是在说如果 \(x\) 合法,那么 \(x + 1\) 也合法。

这启示我们二分答案,然后通过上面的做法来 check。

63.P4003 无限之环

先考虑如果给你一张图怎么判断是否漏水。

按照套路黑白染色后黑白之间连边,如果满流就说明不漏水。

要操作次数最少,考虑拆点后通过费用表示操作次数。

将每个格子拆成 5 个点,分别表示上、右、下、左方向上的接口、这个格子。

下面记水管接口状态为 \(S\)\((u, v, cap, cost)\) 表示从 \(u\)\(v\) 连一条流量为 \(cap\),费用为 \(cost\) 的边,\(\operatorname{id}(x, y, o)\) 表示 \((x, y)\) 位置拆成的第 \(o\) 个点的标号。

下面的讨论的都是白点,黑点是对应的。

\(\text{Case1: }\operatorname{popcount}(S) = 1\)

不妨钦定接口是朝上的。

那么我们只需要 \((\operatorname{id}(x, y, 4), \operatorname{id}(x, y, 0), 1, 0)\)\((\operatorname{id}(x, y, 0), \operatorname{id}(x, y, 1), 1, 1)\)\((\operatorname{id}(x, y, 0), \operatorname{id}(x, y, 2), 1, 2)\)\((\operatorname{id}(x, y, 0), \operatorname{id}(x, y, 3), 1, 1)\) 即可.

\(\text{Case2: } \operatorname{popcount}(S) = 2\)

对于直线形的水管,没有需要多连的边。

对于直角形的水管,钦定接口是朝上和朝右的,上向下连一条 1 费用的边,右向左连一条 1 费用的边。

\(\text{Case3: }\operatorname{popcount}(S) = 3\)

钦定接口是朝上、左、右的,那么需要上向下连一条费用为 2 的边,左、右向下连一条费用为 1 的边。

然后跑费用流即可。

64.P2053 [SCOI2007] 修车

每个师傅对答案的贡献是独立的,考虑计算贡献。

记当前的师傅维修的车为 \(a_1, a_2, \cdots, a_n\),那么贡献可以写成 \(\sum_{i} a_i \cdot(n - i + 1)\)

\(a\) reverse 一下,就变成 \(\sum_i a_i \cdot i\)

考虑将每个师傅拆成 \(n\) 个点,表示第一次修、第二次修……

然后按贡献连边即可。

65.P2050 [NOI2012] 美食节

上一题的加强版。

发现有用的点只有 \(O(P)\) 个,所以考虑只建出这些点。

再观察,发现对每个厨师来说合法的点都是一段前缀。

所以考虑初始只建贡献为 1 的点,每次只要一个点到 \(T\) 之间的边流满了就加入这个厨师的下一个点即可。

这样点数就是 \(O(n + m + P)\) 级别的了。

66.P3749 [六省联考 2017] 寿司餐厅

考虑最小割建模。

对每个区间和每个代号建点,从源点向这个点连边,从这个点向汇点连边。

我们称一个点是选择的当且仅当源点通过没被割的边能到达这个点,否则称这个点没被选择。

对于区间 \([l, r] \ (l < r)\),我们向 \([l + 1,r]\)\([l, r - 1]\) 分别连 \(+ \infty\) 的边,表示选了 \([l, r]\) 就一定选它的子区间。

对于区间 \([l, r]\),若 \(d_{l, r} > 0\),那么我们先将 \(ans := ans + d_{l, r}\),然后连边 \((S, [l, r], d_{l,. r})\) 表示不选就有 \(d_{l, r}\) 的代价;若 \(d_{l, r} < 0\),那么连边 \(([l, r], T, - d_{l, r})\) 表示选就有 \(- d_{l, r}\) 的代价。

对于一种寿司 \(i\),连边 \((i, T, a_i)\) 表示选则有 \(a_i\) 的代价,同时连边 \((i, a_i, + \infty)\) 表示选了 \(i\) 就一定会选 \(a_i\) 这个标号。

对于一个标号 \(x\),连边 \((x, T, mx^2)\) 表示选这个标号就有 \(mx^2\) 的代价。

这张图的最小割即为最小代价。

67.P3308 [SDOI2014] LIS

先不考虑字典序的条件,考虑如何计算答案。

首先 DP 求出 LIS,考虑将转移关系建成一张图。

因为是要删点,所以可以将每个点拆成入点和出点,边权为 \(b_i\)

这样这张图的最小割即为答案。

对于字典序的限制,我们按 \(C\) 排序,从小到大考虑每条边能不能割。

如果能割就加入到答案里,退流后删掉即可。

68.P5295 [北京省选集训2019] 图的难题

首先可以猜一个结论:充要条件是对于所有子图,\(\lvert E \rvert \le 2 \lvert V \rvert - 2\)

这是对的,证明可以看题解。

然后移一下项可得:\(\max \{ \vert E \rvert - 2 \lvert V \rvert \} \le - 2\)

也就是说,如果我们把边权看做 1,点权看做 -2,那么我们的要求就是最大的权值和 \(\le - 2\)

这是最大权闭合子图的形式,可以直接流。

但是有个问题就是如果我们选了空的图,那么左式是等于 0 的,所以我们需要钦定选一个点然后流。

这个可以通过退流实现。

69.CF903G Yet Another Maxflow Problem

首先转成最小割。

不难发现割的形态一定是 \(A\) 的链上割一条边,\(B\) 的链上割一条边,然后割掉其余的还没割掉的 \(A \rightarrow B\) 的边。

发现剩下的边是二维偏序的形式,所以考虑放到二维平面里。

如果横坐标是 \(A\),纵坐标是 \(B\),那么其余的边就是一个左上角的矩形。

所以通过扫描线我们可以计算出割掉 \(A_i \rightarrow A_{i + 1}\) 这条边时的最小代价。

然后修改就是单点改,求全局最大值,这个可以可删堆维护。

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

70.CF2026F Bermart Ice Cream

先考虑如果只有一家商店怎么做。

问题变成了维护一个物品序列,支持 push back、pop front、求背包。

这个可以通过用栈模拟 queue 来完成。

对于原问题,可以离线建操作树,然后在操作树上 DFS。

现在需要支持 push back、push front、pop back、pop front、求背包。

这个可以通过两个栈模拟 deque 完成。

时间复杂度 \(O(q \max p)\)

71.Educational Codeforces Round 171 (Rated for Div. 2)

solution

72.CF1861F Four Suits

首先计算出每个人还需要的卡牌数,记为 \(need_i\)

枚举每个人和他手中最大的卡牌,计算答案。

此时我们的要求是其他人每种卡牌的数量的最大值最小,考虑二分答案。

记当前二分的值为 \(mid\),那么对于第 \(i\) 个人的第 \(j\) 种卡牌,要求是个数 \(\le mid - a_{i, j}\)

这是流的形式,所以我们对每种卡牌建一个点,从源点向它连流量为 \(b_j\) 的边,从它向每个人连流量为 \(mid - a_{i, j}\) 的边,每个人向汇点连流量为这个人还需要的卡牌数的边。

如果这张图满流,那么这次 check 就是成功的。

但是我们每次流一遍显然是不现实的,套路的考虑转成最小割去做。

枚举源点和四张卡牌的连边状态 \(S\) 后,每个人还需要 \(\min(need_i, \sum_{j \not \in S} mid - a_{i, j})\) 的代价。

考虑这个式子什么时候取到第一项:

\[\begin{aligned} need_i &\le \sum_{j \not \in S} mid - a_{i, j} \\ need_i - \sum_{j \not \in S} a_{i, j} &\le mid \cdot \sum_{j \not \in S} 1 \\ \end{aligned} \]

这样就可以预处理后二分了。

时间复杂度 \(O(nm 2^m \log V \log n)\),可以通过桶做到 \(O(nm 2^m \log V + 2^m V)\)

73.CF1662J Training Camp

考虑一种合法的方案意味着什么。

如果我们把同行同列的相差为 1 的位置从小往大连边,那么选出的点一定是把图分成了两个不联通的部分。

拆点后就转化成最小割了。

74.CF786B Legacy

线段树优化建图板子。

75.P5331 [SNOI2019] 通信

流的建模应该是简单的,就是每个哨站建成两个点分别表示直接流出和被连接。

然后建图就是源点向每个点连流量为 1,费用为 0 的边,每个点向汇点连流量为 1 的边。

然后每个表示直接流出的点向每个表示被连接的点连流量为 1,费用为 \(\lvert a_i - a_j \rvert\) 的边。

现在主要的问题就是边数是 \(O(n^2)\) 级别的。

考虑分治优化建图,每次将分治中心右边的点向分治中心左边的点连边。

考虑怎么解决费用的问题,这部分可以通过费用的累积解决。

具体来说,可以把 \([l, r]\) 中的 \(a\) 拉出来排序离散化,拉成一条链,然后连边就是每个点向链上对应权值的点连边。

这样点数边数就是都是 \(O(n \log n)\) 的了。

76.P1341 无序字母对

欧拉回路。

posted @ 2024-10-24 19:35  definieren  阅读(21)  评论(0编辑  收藏  举报