2023.12.22~ 做题记录

1. ICPC2022 Xi'an R A Bridge

感觉很妙啊,应该不止蓝吧?

首先一个转化是每次建桥操作就相当于交换两条链的后半部分,可以看看扶苏那篇题解的图。

我们将每个点表示为形如 \((x, y)\) 的二元组表示它初始在第 \(x\) 行第 \(y\) 列,按 \(y\) 为键值排序,那么一次询问就是查询一条链的最大值。

这些操作可以用 FHQ Treap 完成,就是每次修改 \((a, b)\) 就把两棵 Treap 分别按 \(\le b\) split 成四棵,交换后再 merge。查询直接暴力跳右儿子就行。

但是显然不能存 \(nm\) 个点。考虑我维护连续段而不是维护一个个单点,每个连续段形如 \((x, l, r)\) 表示初始在第 \(x\) 行第 \(l\) 列到第 \(r\) 列的点,意义是它们在同一条链上并且连边 \(l \to l + 1 \to \cdots \to r\)

那么每次修改操作会多产生 \(4\) 个段,所以段的个数就是 \(O(n + q)\) 的,可以接受。

实现时比较繁琐,每一行要额外开个 set 维护原来在这一行的段方便对于每次修改找到 \(b\) 所在的段,还要开个 map 维护每个三元组 \((x, l, r)\) 对应到 Treap 上的哪个点。为了找对应结点的根还要维护每个点的父亲。

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

2. P1742 最小圆覆盖 / [ABC151F] Enclose All

随机增量法,打乱后每次枚举三个点,若不在最小圆上就重新求一遍它们的外接圆。期望复杂度 \(O(n)\)

3. QOJ7934 Christmas Sky

考虑二分答案,相当于求出一个定圆覆盖 \(nm\) 个点。所以可以不用二分,直接对这 \(nm\) 个点求最小圆覆盖即可。

或者可以闵可夫斯基和合并凸包,做 \(O(n \log n + m \log m)\)

4. QOJ7943 LIS on Grid

好题。

首先可以视为每一列 \(1\) 的个数 \(\ge a_i\),超出的最后再无视即可。

首先先不考虑构造。考虑二分 \(k\),考虑 Dilworth 定理,即询问是否有 \(k\) 条链覆盖所有的黑格。

可以调整使得第 \(i\) 条链的起点为 \((n - k + i, 1)\),终点为 \((i, m)\)

那么一条链往上走的次数都为 \(n - k\)

因为一条链必定至少经过一遍每一列,所以不妨令 \(b_i = \max(0, a_i - k)\)

那么也就是第 \(i\) 列需要往上走至少 \(b_i\) 次。

一个显然的必要条件是 \(\sum\limits_{i = 1}^m b_i \le k (n - k)\)。后面我们通过构造方案证明这是充要的。

贪心按链从前往后构造。对于第 \(i\) 条链,贪心地使它满足最前面的若干个上升。

容易发现此时若两条链重合就相当于 \(b_i > n - k\),与题目条件矛盾。

所以上述条件是充要的。直接这样构造即可。

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

5. P7828 [CCO2021] Swap Swap Sort

考虑每次交换答案的增量,显然为 \(|S_x| \times |S_y| - 2 \times f(p_x, p_{x + 1})\)。其中设 \(S_x\)\(x\) 出现的位置,那么 \(f(x, y) = \sum\limits_{i \in S_x} \sum\limits_{j \in S_y} [i > j]\)

考虑经典根号分治,\(|S_x| < B\) 称之为小类,\(|S_x| \ge B\) 称之为大类。小类可以暴力双指针做,大类因为不超过 \(\frac{n}{B}\) 个可以离线下来扫一遍。总时间复杂度为 \(O(\frac{n^2}{B} + qB)\)\(B = \sqrt{\frac{n^2}{q}} = 100\) 最优。

6. CF331E2 Deja Vu

考虑一条好的路径 \(x \to y\) 中一定至少存在一条边 \((u, v)\),满足这条边的序列 \(a\) 存在一个 \(j \in [1, |a| - 1]\),满足 \(a_j = u, a_{j + 1} = v\),就是说 \(a\) 包含一对相邻的 \((u, v)\)

那么我们可以枚举这样的边 \(u \to v\),将这条边的序列 \(a\) 分成 \([\ldots, u], [v, \ldots]\) 的部分,然后两端独立地分别扩展,直到当前序列长度等于已经经过的点数。

找这样的一条路径复杂度 \(O(nm)\),可以通过 E1。

考虑我们上面的找法,实际上是找到了一些极小的好的路径(就是只存在一条边 \((u, v)\),满足边序列恰好包含一对相邻的 \((u, v)\))。我们希望用一些这样的路径拼出其他的好的路径。

我们可以在两条好的路径中间用一条边序列为空的边拼起来,或者在一条好的路径后面接一条“边序列在开头加上起点等于经过的点序列”的路径,或者在前面接一条“边序列在末尾加上终点等于经过的点序列”的路径。

所以我们可以用一个形如 \((x, y, k, p = 0/1, q = 0/1)\) 的五元组表示一条 \(x \to y\) 的极小的路径,长度为 \(k\),边序列是否包含起点,边序列是否包含终点(都为 \(0\) 说明这是一条 \(x \to y\) 的边序列为空的边)。那么两个三元组能拼接起来当且仅当前者的终点是后者的起点且前者的 \(q\) 异或后者的 \(p\)\(1\)

所以现在就能做一个背包 dp 了,设 \(f_{u, i, 0/1}\) 表示当前走到 \(u\),构成的路径长度为 \(i\),边序列是否包含终点。按长度从小到大转移即可。

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

7. [ARC141F] Well-defined Abbreviation

答案是 Yes 的充要条件是,删除可以被一些串拼接而成的串后,不存在 \(S_i\)\(S_j\) 的子串,并且不存在串 \(A, B, C\),使得 \(AB \in S, BC \in S\)\(A \ne C\)

第一步考虑删除可以被一些串拼接而成的串。按长度从小到大考虑每个串,每次遇到能删的后缀就尽量删,若删不完说明不满足第一个条件,若没删就可以把它加入 \(S\)。这一步可以考虑建 AC 自动机,然后 fail 树上子树覆盖。

第二步考虑判第二个条件。考虑哈希,枚举 \(B\),维护对应的 \(A, C\) 的集合是否存在两个不等元素。

时间复杂度应该是 \(O(m \log m)\),其中 \(m = \sum |s_i|\)

8. [ARC168C] Swap Characters

vp 了一场 ARC。

考虑对于一个固定的 \(t\) 计算最小代价。显然先搞定二元环再搞定三元环。这里有个很像的题

\(AB \ge BA\)\(AB\)\(A \to B\) 出现的次数,其他同),那么我们需要满足 \(AB - BA = BC - CB = AC - CA = k\),最小代价即为 \(BA + CB + CA + 2k\)。显然枚举其中 \(4\) 个即可。方案数随便组合数算一下。

\(AB < BA\) 的情况同理。

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

9. [ARC168D] Maximize Update

为啥我的区间 dp 这么复杂。

\(f_{l, r}\) 表示覆盖完 \([l, r]\) 的最大收益,\(g_{l, r}\) 为至少有一个格子没被覆盖时的最大收益。

考虑转移就是枚举一条线段 \([L, R]\),若 \(L < l \land r < R\) 就有 \(f_{L, R} \gets \max(g_{L, i - 1} + f_{i, j} + f_{j + 1, R} + 1, \max(f_{L, i - 1}, g_{L, i - 1}) + f_{i, j} + g_{j + 1, R} + 1)\)。其他两种情况类似。

然后这个东西容易通过合理地预处理做到 \(O(n^3)\)。代码挺复杂的。

看题解发现怎么只枚举一个格子就行了。感觉自己太蠢了。

10. [ABC334G] Christmas Color Grid 2

考虑相当于把每个标记点的边全部断掉,然后求连通块个数。

考虑一条边 \((u, v)\)(设 \(u < v\))的出现时间,不难发现是 \([1, u - 1] \cup [u + 1, v - 1] \cup [v + 1, n]\)。于是考虑直接套线段树分治和可撤销并查集。

时空复杂度均为 \(O(n^2 \log n)\)。实现得别太随意就能过了。

11. CF1909F2 Small Permutation Problem (Hard Version)

感觉这个题还是挺不错的。

考虑 F1。考察 \(a_i\) 差分后的意义,发现 \(a_i - a_{i - 1}\) 就是 \((\sum\limits_{j = 1}^{i - 1} [p_j = i]) + p_i \le i\)

考虑将其转化为棋盘问题。在 \((i, p_i)\) 放一个车,那么 \(a_i - a_{i - 1}\) 就是 \((1, i) \sim (i, i)\)\((i, 1) \sim (i, i - 1)\) 这些格子组成的“L”字形的车的数量。

一个放车的方案合法当且仅当所有车互不攻击。因此容易发现合法的 \(a_i - a_{i - 1}\) 一定 \(\in [0, 2]\)。考虑从前往后扫,同时维护答案 \(ans\) 和现在还没被占用的行(列)数量 \(t\)

  • \(a_i = a_{i - 1}\),无事发生,多了第 \(i\) 行和列没被占用,因此 \(t \gets t + 1\)
  • \(a_i - a_{i - 1} = 1\),相当于可以在 \((1, i) \sim (i - 1, i)\)\((i, 1) \sim (i, i - 1)\) 中还没被占用的格子放车,同时也可以在 \((i, i)\) 放车,那么 \(ans \gets ans \times (2t + 1)\)\(t\) 不变。
  • \(a_i - a_{i - 1} = 2\)\((1, i) \sim (i - 1, i)\)\((i, 1) \sim (i, i - 1)\) 中还没被占用的格子各放一个车,那么 \(ans \gets ans \times t^2\),然后 \(t \gets t - 1\)

如上讨论可以通过 F1

F2 我们继续将其放到棋盘上考虑。考虑一个 \(a_i \ne -1\) 的位置 \(i\),设它上一个 \(a_j \ne -1\) 的位置是 \(j\)。现在相当于求在 \(y \times y\) 的左下角抠掉了 \(x \times x\) 的一块的“L”字形棋盘放 \(t\) 个互不攻击的车的方案数,其中 \(x = j - a_j, y = i - a_j, t = a_i - a_j\)。每个这样的“L”字形互相独立,所以可以直接把方案乘起来。

上面的问题可以考虑容斥(我现在还不会不容斥的做法?)。相当于在左下角 \(x \times x\) 的区域不能放车,那么我钦定 \(i\) 个车放在了左下角,设 \(F(n, m)\)\(n \times n\) 的棋盘放 \(m\) 个互不攻击的车的方案数,那么这部分的方案为 \(F(x, i) \times F(y - i, t - i)\),容斥系数为 \((-1)^i\),因此结果为:

\[\sum\limits_{i = 0}^t (-1)^i F(x, i) F(y - i, t - i) \]

最后一个问题是求 \(F(n, m)\)。考虑先选 \(m\) 行放车,有 \(\frac{n!}{(n - m)!}\) 种选列的方案,那么 \(F(n, m) = \binom{n}{m} \times \frac{n!}{(n - m)!}\)

容易发现 \(\sum t = n\),所以时间复杂度为 \(O(n)\)

12. CF1909E Multiple Lamps

感觉这个题比较难蚌。

发现按 \(1 \sim n\) 最后可以把 \(1 \sim n\) 中的所有平方数点亮。所以 \(n \ge 20\) 就直接输出 \(1 \sim n\)

考虑 \(n \le 19\)。猜测合法的方案(即按完后亮灯数 \(\le \left\lfloor\frac{n}{5}\right\rfloor\) 的方案,不考虑 \((u, v)\) 的限制)不会很多。打表发现 \(n = 19\) 时仅有 \(1159\) 种。于是把合法方案预处理出来即可。

赛时智障了,所以直接把表放到代码里了。

13. CF1909D Split Plus K

设最后每个数都相等时为 \(t\)。那么一次操作变成了合并两个数 \(x, y\),再增加 \(x + y - k\)。于是每个 \(a_i\) 可以被表示成 \(b_i t - (b_i - 1)k\) 的形式,化简得 \(a_i - k = b_i (t - k)\)

因为 \(t - k\) 对于每个 \(i\) 都相同,又因为我们的目标是最小化 \(\sum\limits_{i = 1}^n b_i\),所以 \(t - k\)\(\gcd\limits_{i = 1}^n (a_i - k)\) 最优。

注意所有 \(a_i - k\) 同号才合法,以及特判掉初始 \(a_i\) 全部相同的情况后不能出现 \(a_i = k\)

14. [ARC168E] Subsegments with Large Sums

尝试二分答案,问题变为要求恰好选 \(x\)\(\ge s\),最大化选的段数。

发现我们不是很会算段数的 \(\max\),考虑给每个段 \([l, r]\) 一个长度减一即 \(r - l\) 的代价,于是变成了算代价的 \(\min\)

\(f(x)\) 为分成的若干段中包含恰好 \(x\)\(\ge s\) 段,每一段 \([l, r]\) 的代价定义为 \(r - l\),代价的 \(\min\)。那么一个答案 \(x\) 合法当且仅当 \(f(x) \le n - k\)。若一段 \(< s\) 那么它没有贡献,所以最优的情况一定是一个数自成一段,代价就是 \(0\)。于是我们只用考虑 \(\ge s\) 的代价之和。

发现 \(f(x)\) 下凸(感性理解就是选的段的代价会越来越大),那么 \((x, f(x))\) 构成一个下凸包的右半边(即斜率 \(> 0\) 的部分)。套路地 wqs 二分斜率 \(k\),选一个 \(\ge s\) 段的代价变成 \(r - l - k\),在此基础上求选出若干段的代价 \(\min\) 和在取到这个 \(\min\) 的前提下至少选了多少段即可。

上面那个问题显然可以 dp 求出。dp 数组单调,所以只用考虑最近的一个合法转移点转移过来(即对于每个 \(i\) 满足 \(\sum\limits_{k = j}^i a_k \ge s\) 的最小的 \(j\))即可。

预处理每个位置的最近合法转移点,总时间复杂度 \(O(n \log^2 n)\)

15. CF1906K Deck-Building Game & UOJ310 [UNR #2] 黎明前的巧克力

枚举两个人选的卡的并集 \(S\),那么当 \(\bigoplus\limits_{i \in S} a_i = 0\)\(S\) 有贡献 \(2^{|S|}\)

考虑将 \(2^{|S|}\) 分摊到每个元素上,也就是每个元素有 \(2\) 的贡献,然后把这些贡献乘起来。所以题目其实是想让我们算这个东西:\([x^0] \prod\limits_{i = 1}^n (1 + 2x^{a_i})\),定义 \(x^i \times x^j = x^{i \oplus j}\)

\(F_i(x) = 1 + 2x^{a_i}\),考虑给每个 \(F_i\) FWT 一下,对位乘后再逆 FWT 回去。因此我们已经有了一个 \(O(nV)\) 的做法,显然不能通过。

考虑 \(F_i\) FWT 后的结果,因为此处 \(\text{FWT}(a)_i = \sum\limits_{j} (-1)^{\text{popcount}(i \& j)} a_j\),容易发现 \(\text{FWT}(F_i)\) 只含有 \(3\)\(-1\)。因此我们对位乘后第 \(i\) 位的结果可以表示成 \((-1)^{x_i} 3^{n - x_i}\)

\(G = \text{FWT}(F_1) + \text{FWT}(F_2) + \cdots + \text{FWT}(F_n)\),那么我们有 \(-x_i + 3(n - x_i) = G_i\)。解得 \(x_i = \frac{3n - G_i}{4}\)。又因为 FWT 的线性性我们有 \(G = \text{FWT}(F_1 + F_2 + \cdots F_n)\),所以 \(G_i\)\(x_i\) 都能快速求出来。所以我们求出这样对位乘后第 \(i\) 位的结果,最后再逆 FWT 回去即可得到 \([x^0] \prod\limits_{i = 1}^n F_i\)

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

16. P9989 [Ynoi Easy Round 2023] TEST_69

考虑一个数取 \(\gcd\) 次数不超过 \(\log a_i\)。势能线段树维护一下即可。要维护区间 \(\text{lcm}\)

17. CF1917D Yet Another Inversions Problem

同行之间的逆序对直接算一行的然后 \(\times n\),考虑不同行的。

对于 \(i < j\),如果一对 \((x, y)\) 能产生贡献,就有 \(p_i \times 2^x > p_j \times 2^y\);若 \(p_i < p_j\),有 \(y - x < \left\lfloor\log_2 \frac{p_i}{p_j}\right\rfloor\)\(p_i > p_j\) 类似。

那么我们可以树状数组处理出一些 \(c_i\) 表示 \(y - x < i\)\(c_i\) 的贡献。然后就随便做了。

18. CF1917F Construct Tree

考虑形式化地描述这个问题。先把 \(l\) 排序。然后相当于是否存在一个 \(\{1, 2, \ldots, n\}\) 的子集 \(S\),使得:

  • \(\sum\limits_{i \in S} l_i = d\)
  • \(\exists T \subseteq S, \max\limits_{i \notin S} l_i \le \min(\sum\limits_{i \in T} l_i, \sum\limits_{i \in S \land i \notin T} l_i)\)

注意到若 \(n - 1 \in S \land n \in S\) 则第二个条件一定满足,让 \(n - 1 \in T\)\(n \notin T\) 即可。所以如果 \(l_1, l_2, \ldots, l_{n - 2}\) 能凑出来 \(d - a_{n - 1} - a_n\) 就可行。

然后依次讨论 \(\max\limits_{i \notin S} i = n - 1\)\(n\) 的情况。

  • \(\max\limits_{i \notin S} i = n - 1\),那么 \(n \in S\)。若前 \(n - 2\) 个元素能凑出来和为 \(x\)\(d - x - a_n\) 的两个不相交集合,且 \(a_{n - 1} \le \min(x + a_n, d - x - a_n)\) 就可行。
  • \(\max\limits_{i \notin S} i = n\),那么若前 \(n - 1\) 个元素能凑出来和为 \(x\)\(d - x\) 的两个不相交集合,且 \(a_n \le \min(x, d - x)\) 就可行。

二维可行性背包考虑 bitset 优化,复杂度 \(O(\frac{nd^2}{\omega})\)

19. CF1917E Construct Matrix

\(2 \nmid k\) 显然无解。

\(4 \mid k\),发现给一个全 \(2 \times 2\) 子矩形全部异或 \(1\) 不会对行异或和和列异或和造成影响。那么我们找到 \(\frac{k}{4}\) 个全 \(0\)\(2 \times 2\) 子矩形填 \(1\) 即可。

否则若 \(k = 2\)\(k = n^2 - 2\),除 \(n = 2\) 外无解。

否则我们有一个 \(k = 6\) 的构造,即令 \(a_{1, 1} = a_{1, 2} = a_{2, 1} = a_{2, 3} = a_{3, 2} = a_{3, 3} = 1\)

\(k\) 更大,把左上角的 \(4 \times 4\) 矩形抠掉后再找 \(2 \times 2\)\(0\) 矩形,全部填 \(1\)

\(k\) 还有剩余,在左上角 \(4 \times 4\) 矩形中找和为 \(1\)\(2 \times 2\) 子矩形,全部异或上 \(1\),可以使得这个子矩形的和变为 \(3\)。重复这样找直到 \(k\) 被消耗尽即可。容易发现一定能找到这样的子矩形。

20. [ARC168F] Up-Down Queries

貌似是第三道问号题?感觉前面这个转化不是人能想到的。。。

考虑维护 \(y\) 的差分序列。更进一步地,我们类比 slope trick,维护一个可重集,里面有 \(y_{i + 1} - y_i\)\(i\)(为了方便我们让每次操作时 \(y_{m + 1}\)\(1\))。那么一次操作就相当于,插入两个 \(a_i\),删去最小值。

考虑统计答案。如果不考虑 \(\max\) 操作就是 \(\sum\limits_{i = 1}^n m - 2a_i\)。考虑 \(\max\) 操作,相当于每次有最小值个数避免了减 \(1\)。所以答案每次再加上最小值。

于是求 \(f(a)\) 可以转化为:从左往右遍历 \(a\),往可重集中加入 \(2\)\(a_i\),把此时可重集的最小值累加进答案,再删除最小值。

考虑倒着操作,转化为从右往左遍历 \(a\),往可重集中加入 \(2\)\(a_i\),删除可重集中的最大值。最后可重集中的数的和就是答案。

这样就转化成了一个比较标准的 P9168 [省选联考 2023] 人员调度 的链的问题了。简单讲一下这个问题的做法。

考虑初始时一个数也没有,然后我们在一些位置加数。加数的同时维护最后还在可重集中的数。

设当前要加的数的位置是 \(u\),数值是 \(x\)。我们找到 \(u\) 的祖先即 \([1, u]\) 中最后一个满的位置 \(v\)(一个点 \(v\) 满了指 \(v\) 的子树即 \([v, n]\) 中数的个数 \(= sz_v = n - v + 1\))。

如果 \(v\) 不存在我们放心把这个数加入即可,因为不会造成 pop。

否则,我们找到 \(v\) 的子树中的最大值,设其权值为 \(w\)

\(x > w\),那么 \(x\) 加入后在 \(v\) 位置一定会被 pop,所以不用加入。

否则,因为 \(w\) 不会被 pop,所以 \(x\) 也不会被 pop。于是我们直接用 \(x\) 替换 \(w\) 即可。

注意到我们不能删除,考虑线段树分治变删除为撤销即可。

实现时需要一棵线段树维护每个位置的 \(sz\) 减去其子树内数的个数,一棵线段树维护子树中所有数的最大值,配合 \(n\) 个可重集维护每个点上的数。

时间复杂度 \(O(n \log^2 n)\),需要卡常。卡常主要两点,第一棵线段树不要用 pair 维护最小值及其位置,改成线段树上二分;注意到可重集中至多两个元素,所以可以手写。

21. P9340 [JOISC 2023 Day3] Tourism

有一个显然的 \(O(m \sqrt{q})\) 回滚莫队做法。答案为按 dfn 序排序后相邻两点距离之和。但是太烂了。

考虑更聪明的做法。发现答案是,对于每个 \(a_i\),其中 \(i \in [l, r]\),把 \(a_i\) 到根的路径染色,答案即为染色的点减去这些点的 lca 深度。

后者是好处理的。考虑前者。考虑按 \(l\) 扫描线,每次把 \(u\) 到根的路径染成 \(l\) 色。询问即查询有多少个点的颜色 \(\le r\)

考虑树剖后拍到 dfn 序上,维护一个 ODT 即可。

但是注意到每次对重链的染色是一段前缀,直接每个重链维护一个 vector 即可。

总时间复杂度 \(O(m \log^2 n)\)

22. CF802B Heidi and Library (medium)

显然的贪心策略:每次如果满了就把下一次出现的位置最大的书扔掉。

23. P9058 [Ynoi2004] rpmtdq & P9678 [ICPC2022 Jinan R] Tree Distance

类比 P9062 [Ynoi2002] Adaptive Hsearch&Lsearch 处理区间最近点对的思路,尝试只保留可能有贡献的点对。

处理树上路径容易想到点分治。设点 \(u\) 到分治中心的距离为 \(a_u\)。我们有 \(\text{dis}(u, v) \le a_u + a_v\)

考虑一个点对 \((u, v)\) 什么时候一定没贡献。这里默认 \(u, v\) 跨过分治中心,若不跨过并且在这一层舍弃了还可以在下一层重新被考虑。若存在 \(w \in [u + 1, v - 1]\) 使得 \(\text{dis}(u, w) \le a_u + a_v\)\(\text{dis}(w, v) \le a_u + a_v\) 那么 \((u, v)\) 就没用,放缩一下有 \(a_w \le a_v\)\(a_w \le a_u\)。所以一个点对 \((u, v)\) 要满足 \(\max(a_u, a_v) < \min\limits_{i = u + 1}^{v - 1} a_i\) 才可能有贡献。

分类讨论一下。如果 \(a_u \le a_v\),那么 \(u\) 必须是 \(v\) 之前第一个比 \(a_u\) 小的点,用单调栈求一下即可。如果 \(a_u \ge a_v\) 那么 \(v\) 必须是 \(u\) 之后第一个比 \(a_v\) 小的点,倒着再做一遍即可。

根据上面的求法我们可以得到有贡献点对数量是 \(O(n \log n)\) 的。

接下来就是套路的扫描线了。扫右端点 \(r\),每次把 \(v = r\) 的点对加入。那么一次询问 \(l\) 就是查询 \([l, n]\) 的后缀最小值。树状数组维护即可。

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

24. P5311 [Ynoi2011] 成都七中

转化一下题意,变成求 \(x\) 在只经过编号 \(\in [l, r]\) 的点,能走到多少种颜色。

考虑建出点分树。一个结论是原树上的一个连通块,一定存在一个点,使得它在点分树上的子树完全包含这个连通块的所有点。证明考虑点分治的过程,一个连通块如果没被其中一个点剖开就一定在同一个子树。

所以对于一个询问 \((l, r, x)\),我们可以把 \(x\) 跳到点分树上最浅的与 \(x\) 在同一连通块的点 \(y\)。判断两个点是否在同一连通块只需求路径最小值和最大值,可以树剖 + ST 表解决。

这样问题变为子树内的问题了,即一次询问要求点分树上 \(y\) 的子树内,到 \(y\) 的路径最大值 \(L \ge l\),最小值 \(R \le r\) 的这些点中不同的颜色 \(c\) 数量。

因为点分树上 \(\sum sz_u = O(n \log n)\) 所以可以暴力遍历子树求出所有的 \((L, R, c)\)。套路地离线扫描线,扫右端点 \(r\),同时加入所有 \(R \le r\) 的点。设 \(b_x\) 为颜色 \(x\) 的左端点最大值。那么一种颜色 \(c\) 对于一个 \(l\)\(b_c \ge l\) 时有 \(1\) 的贡献。树状数组维护即可。

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

25. [ARC167D] Good Permutation

不懂,怎么 friends 人均计数大师,过了 C 没过 D 的。感觉这题很好想的。

显然好的排列是 \(i \to p_i\) 后只有一个环的排列。

考虑最小化 \(p_1\)。将 \(1\) 与在 \(1\) 后面的和 \(1\) 不在同一个连通块的点的 \(p\) 值最小的点 \(x\) 交换即可。注意要满足 \(p_x < p_1\) 才能交换,不能会变劣。

然后再考虑最小化 \(p_2, p_3\),一直到 \(p_n\)

但是可能做完上面的过程后环没有被全部合并。这时候我们不得不增大字典序了。为了最小化字典序我们从后往前扫,对于点 \(i\) 仍然找到在 \(i\) 之后的 \(p\) 值最小的点 \(x\) 交换,只是不再要求满足 \(p_i < p_x\)

为了快速维护这个东西我用了并查集启发式合并和线段树维护区间最大和次大的 \(p\)(强制要求最大和次大不能在同一连通块),时间复杂度 \(O(n \log^2 n)\),有点难写。

26. [ARC167C] MST on Line++

我是傻逼。很平凡的一个计数。但是不会啊。怎么会是呢。

考虑 Kruskal 求解 MST on Line 问题。我们可以想到统计边权 \(= a_i\) 的出现次数。

然后又可以容斥转化成统计边权 \(\le a_i\) 的出现次数,设其为 \(f_i\)

考虑求 \(f_i\)。就相当于把 \(p\)\(\le i\) 的位置集合 \(q\) 拿出来,求 \(\sum\limits_{j = 2}^i [q_j - q_{j - 1} \ge k]\)

枚举 \(q_j - q_{j - 1} = t\),有方案数 \(\binom{n - t}{i - 1}\),并且不难发现每个 \(j\) 相互独立且方案数相等。

所以:

\[f_i = i! (n - i)! (i - 1) \sum\limits_{j = 1}^i \binom{n - j}{i - 1} \]

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

posted @ 2023-12-22 09:52  zltzlt  阅读(80)  评论(0)    收藏  举报