7.18 做题记录

P8348 「Wdoi-6」未知之花魅知之旅

将序列视为形如 \((a_0, a_1) \to (a_1, a_2) \to \dots \to (x, y)\) 的转移序列。
考虑什么样的转移 \((x, y) \to (y, z)\) 合法。

\(\max \lbrace y, z \rbrace \gt \max \lbrace x, y \rbrace\),则 \(z = x + y\)

\(\max \lbrace y, z \rbrace \le \max \lbrace x, y \rbrace\),则 \(z = |x - y|\)

考虑一棵无限大的二叉树,节点编号为二元组,\((x, y)\) 的左右孩子分别为 \((y, x + y)\)\((x + y, x)\),可以证明我们通过上述操作可以在二叉树上任意游走,那么走的一定是树上简单路径,通过辗转相除法求出 LCA,时间复杂度 \(O(T \log V)\)

总结:

  • 不交 / 包含与树结构的对应(但本题实际不需要考虑这些,是一个直观结构)

CF1209G Into Blocks

对于 easy version,有一个简单的贪心:将所有颜色按照出现次数从大到小排序。一开始预处理出所有颜色第一次出现的位置 \(s_i\) 和最后一次出现的位置 \(t_i\) ,把 \([s_i,t_i]\) 之间的元素都涂成当前颜色,正确的可以讨论一些区间关系证明。

现在要支持修改,如果维护上述贪心的操作序列是非常复杂的,而单点修改这个形式启发我们考虑怎么合并两个区间 \([l,mid],[mid+1,r]\),假设有一个出现次数极大颜色的 \(s,t\) 跨过 \(mid\),假装知道他是什么颜色,那就可以做了,但是问题在于可能有多个候选:跨过 \(mid\) 且不被出现次数更多的颜色包含的颜色,能不能不关心具体是什么呢?

实际上,如果求出 \([1,n]\) 的划分中每个区间是否要求同色,每个同色段里面颜色的限制都是极大的,保留出现次数最大的,这样的贪心满足分治结构,可以线段树套 \(\text{std :: set}\) 维护,时间复杂度 \(O(n \log^2 n)\)

总结:

  • 在不改变最优子结构的前提下舍弃不需要的信息。

P7214 [JOISC2020] 治療計画

建立时间 - 村民二维图,一个治疗计划的覆盖就是一个斜边平行于 \(x\) 轴的等腰直角三角形,那么一个方案合法等价于存在一个三角形的边界轮廓使得 \(1,n\) 联通。

直接建图跑点权最短路,时间复杂度 \(O(m^2)\)

图的结构为一个点向 \(x \leq a_i, y \leq b_i\) 的区域连边,考虑隐式建边的 Dijkstra,每次更新 \(x \leq a_i, y \leq b_i\) 的点,线段树维护每个 \(x\) 坐标上 \(y\) 坐标的最小值由于点权最短路每个点只会被更新一次,每次从前缀中找到最小的 \(y\) 看是否需要删去,时间复杂度 \(O(m \log m)\)

总结:

  • 把复杂的结构直观化(建立坐标系等)
  • 隐式建边最短路

P9067 [Ynoi Easy Round 2022] 虚空处刑 TEST_105

\(C_{i,j}\)\(\text{std::map}\)\(\text{std::list}\))表示 \(i\) 点所在连通块下方的 \(j\) 色连通块序列,直接启发式合并,只需要更新询问的点的父亲信息,时间复杂度 \(O(m \log ^2 n)\)

总结:

  • 树上邻域信息一般把父亲分开考虑

CF1458C Latin Square

如果只有 UDLR 操作,维护两位的错位即可。

现在加入 IC,它们都是整体变换,可以将矩阵的一个位置视为 \((i,j,a_{i,j})\) 这样的三元组,那么 IC 操作就是交换所有三元组的两个元素,记录每个位置上的增量与三元组的顺序即可还原出最后的矩阵,时间复杂度 \(O(n^2 + m)\)

总结:

  • 将不好描述的函数键值化
  • 考虑整体对局部的贡献

P5327 [ZJOI2019] 语言

假设二元组无序,问题转化为维护包含每个点的链并(虚树)在原树上的边数之和。

我们有常见结论,原树上的边数之和等于关键点按 Dfs 序排序后相邻距离之和除以二。

使用线段树维护 Dfs 序,记录一个区间内关键点 Dfs 序的最小/最大值。

考虑将 \(u \to v\) 拆分成 \(u \to \text{lca} , \text{lca}\to v\),那么相当于一条直链上每个位置的线段树都加入 \(u,v\) 的信息,不难利用树上差分与线段树合并做到 \(O((n + m) \log n)\)

总结:

  • 使用线段树维护树上 Dfs 序信息

CF1458D Flip and Reverse

\(1\) 记为 \(+1\)\(0\) 记为 \(-1\),初始有一个变量 \(x = 1\),遍历字符串,将 \(x\) 加上当前位置的值,并在一张图上连上上一个位置的 \(x\)到 当前 \(x\) 的一条有向边。

一次操作相当于选择一个环反向,我们给出以下结论:原图任意一条欧拉回路代表的都可以由原字符串进行一系列操作得到,考虑一个分岔口,最后一定会走回来,那选择这样一个环操作就可以让分岔的两条路径重合。

那么原问题等价于求最小的欧拉序,贪心地,我们每次尝试往 \(x - 1\) 走(首先要有往 \(x - 1\) 的边,另外如果有往 \(x + 1\) 的边,那么往 \(x - 1\) 的边至少需要有两条)即可,时间复杂度 \(O(n)\)

另解:每次选择合法且使当前操作后字典序最小的前缀操作,使用平衡树维护,时间复杂度 \(O(n \log n)\)

正确性证明:你先别急。

总结:

  • 特定模型:序列上选取值有限制的区间操作,考虑建图
posted @ 2023-07-18 22:04  墨珂  阅读(41)  评论(0)    收藏  举报