Solution Set【2024.1.1】

发布时间 2024-01-01 22:04:32作者: User-Unauthorized

实际上本文涵盖了 \(2023.12.30 \sim 2024.1.1\) 之间的题目。

[Ynoi2006] rldcot

考虑如下两个点对:

  • \(\operatorname{lca}(x, y) = \operatorname{lca}(a, b) = u\)

  • \(x \le a \le b \le y\)

容易发现,若 \(\left(x, y\right)\) 被选中,则 \(\left(a, b\right)\) 也一定被选中,称之为 \(\left(a, b\right)\) 支配了 \(\left(x, y\right)\)

因此只需要统计出所有未被支配的点对即可。

考虑什么样的点对是未被支配的。

  • \(\operatorname{lca}(x, y) = u\),则 \(\left(x, y\right)\) 未被支配当且仅当不存在 \(x < z < y\)\(\operatorname{lca}(x, z) = \operatorname{lca}(y, z) = u\)

因此我们可以在固定 \(u\) 的情况下枚举 \(x\),在其他兄弟子树的点集中寻找前驱和后继,即可得到所有未被支配的点对。

这一过程可以通过树上启发式合并实现。具体的,维护一个按标号排序的有序点集,每次保留重儿子的点集,将其他点集合并到重儿子的点集中,在合并其他儿子的点集时统计点对。

每个点会被合并 \(\mathcal{O}(\log n)\) 次,每次会贡献 \(\mathcal{O}(1)\) 个点对,因此有效点对数量为 \(\mathcal{O}(n \log n)\),这部分的时间复杂度为 \(\mathcal{O}(n \log^2 n)\)

接下来问题转化为如何统计答案。

首先我们将数对按最近公共祖先的深度值分组,那么询问 \(\left(l, r\right)\) 可以转化为询问有多少组点对存在点对 \(\left(x, y\right)\),满足 \(1 \le l \le x\)\(y \le r \le n\)

因此我们可以将点对 \(\left(x, y\right)\)\(x\) 的值降序排序,然后维护一个树状数组和一个数组,树状数组用于维护答案,数组用于维护某个颜色 \(c\) 对应的出现过的最小 \(y\) 值,记为 \(last_c\)。那么每次插入一个点对 \(\left(x, y\right)\) 时,若 \(y < last_c\),那么就在树状数组上对区间 \(\left[y, last_c\right)\) 进行区间加操作,然后将 \(last_x\) 更新为 \(y\)。处理询问时单点查询即可。

总复杂度为 \(\mathcal{O}(n \log^2 n)\)

「雅礼集训 2017 Day7」事情的相似度

首先可以通过对字符串建出后缀自动机后将问题放到 \(\tt{parent}\) 树上。这样问题就转化为了给定一个区间,求标号在这个区间内的点对的最近公共祖先的点权最大值。

类似与 [Ynoi2006] rldcot,统计出有效点对后扫描线使用线段树维护最大值即可。

谢特

首先对字符串建出后缀自动机后将问题放到 \(\tt{parent}\) 树上。

接下来问题便为点对贡献问题,对于点对间异或值的最大值可以使用 \(\tt{0-1 \, Trie}\) 解决。而最近公共祖先的权值贡献使用树上启发式合并即可。

也可以使用 \(\tt{Trie}\) 合并来在遍历树的过程中维护答案。

「Cfz Round 3」Circle

首先可以发现给出的函数实质上是在连边 \(i \rightarrow p_i\) 的图中走 \(k\) 步到达的点的标号。

由于 \(p\) 是一个排列,所以这个图是由若干个环组成的。

考虑有解的充要条件,即对于所有 \(S_i = 1\)\(i\),其所在的环的长度 \(k\) 都满足 \(k \mid l\)。由于对于 \(S_i = 0\)\(i\) 无限制,所以我们统计出所有 \(S_i = 1\)\(i\) 的个数 \(C\),这样我们的问题就转化为了:

给定 \(l, C, n\),构造一个可重集,使得其元素均为 \(l\) 的因子,且元素和在 \(\left[C, n\right]\) 之间。

可以发现,若其元素为合数,那么一定可以通过若干质因子构造出来,因此我们可以枚举质因子,然后判断其是否可以存在在集合中。那么可以发现可以在集合中的数只有 \(\mathcal{O}(\log l)\) 种,因此我们可以进行完全背包,进而可以得到方案,时间复杂度为 \(\mathcal{O}(n \log l)\),可以通过。

[LNOI2022] 串

可以发现,将 \(T_0\) 设为空串,\(T_1\)\(S_{1 \dots 1}\),之后每次将左右端点 \(l, r\) 执行 \(l \leftarrow l + 1, r \leftarrow r + 2\) 便可以得到一个 \(\left\lfloor\dfrac{N}{2}\right\rfloor\) 的构造,进而确定了答案下界。

考虑如何优化答案,发现若一个子串在 \(S\) 中出现两次,设其第一次出现右端点为 \(r\),长度为 \(len\),那么可以得到一个 \(len + \left\lfloor\dfrac{N - r}{2}\right\rfloor\) 的构造,对所有出现多次的子串求出最大值即可。


还有四道,明天再写。