Solution Set - “伸手向着拉格朗日点作别”
- 0.「UR #9」「UOJ #133」电路手动分析
- 1.「UR #9」「UOJ #134」App 管理器
- 2.「UR #10」「UOJ #152」汉诺塔
- 3.「UNR #2」「UOJ #312」梦中的题面 ⭐
- 4.「NOI Simu.」战舰
- 5.「UR #10」「UOJ #153」世界线 ⭐
- 6.「洛谷 P9411」Gtrimee
- 7.「CF 1500F」Cupboards Jumps ⭐
- 8.「UR #11」「UOJ #167」元旦老人与汉诺塔
- 9.「NOI Simu.」高维游走 ⭐
- 10.「NOI Simu.」过山车 ⭐
- 11.「NOI Simu.」木棍 ⭐
- 12.「UR #11」「UOJ #169」元旦老人与数列 ⭐
- 13.「UR #12」「UOJ #180」实验室外的攻防战
- 14.「UR #13」「UOJ #186」Yist
- 15.「UR #13」「UOJ #187」Ernd ⭐
Umm… UOJ 浓度极高的一个 sol set. 摘的标题和上一个 sol set 是姊妹篇!
0.「UR #9」「UOJ #133」电路手动分析
- Link & Submission.
二分答案, 尽量把选择的结点排成正方形, 计算边数够不够. .
1.「UR #9」「UOJ #134」App 管理器
- Link & Submission.
枚举未定向边 , 检查去掉这条边后是否存在 或 的路径, 二者中至少存在一个, 据此定向即可. .
2.「UR #10」「UOJ #152」汉诺塔
- Link & Submission.
- 「A.构造」
你这 的操作限制是来骗人的还是来骗兔的?
如何利用 两根空柱子? 把 柱子上的盘子依次取出放入 之一的过程可以看作对 柱子序列的一个划分, 结合排序的目标, 那么自然想到上升/下降子序列. 假设 从上到下读可以划分为 个连续的上升子段, 我们就可以把它们倒到 上, 在两根柱子上各形成 个下降子段. 每次取出两个柱子最顶上的子段归并回 , 子段数量 . 因此 次迭代后必然完成排序. 操作次数 .
3.「UNR #2」「UOJ #312」梦中的题面 ⭐
- Link & Submission.
- 「A.DP-数位 DP」
数位 DP? 啊, 数位 DP!
在 时, 就是 进制下的任意 位数, 由于 个 进制数的加法在某一位上的总进位不超过 , 我们可以暴力记录仅考虑低若干位时, 在当前位的值. 对 , 直接新增一维状态记录有多少个在当前位可以非 (而非留到最高位变成 ) 即可. 最后的状态就是 表示考虑了第 位, 有 个数可以自由填位, 当前位 的方案数. 直接转移可以做到 . 如果从高位向低位 DP 可以得到四方做法, 不过写着比较麻烦.
4.「NOI Simu.」战舰
-
Private link | 卡常, 再见!
-
「B.复杂度平衡」
横纵坐标上的操作相对独立, 我们可以对每一个横坐标维护其一列上的信息, 纵坐标同理. 移动什么的可以直接合并坐标, 加法和查询按照行列长度根号平衡就行了. . 可能有一些很 dirty 的实现细节.
5.「UR #10」「UOJ #153」世界线 ⭐
- Link & Submission.
- 「A.构造」
对于左侧的下标集合 , 我们尝试找到其在右侧对应的集合 . 我们可以把左侧连成若干个大小两两不等的连通块, 再在右侧询问出每个连通块, 这样就能根据连通块大小得到对应关系. 为了得到更确定的对应, 自然的 motivation 就是尝试让左侧集合大小两两不同. 我们可以将左侧标号分组:
可以发现, 左侧的行长度和上侧的列长度构成的坐标可以唯一确定一个单元, 我们就能根据右侧集合所在的行列长度信息直接得到答案.
这个构造只在 时适用, 当 , 我们不可能让行列长度都两两不等, 怎么办呢?
反思一下, 连通块询问带给我们的信息只有 "连通块大小"? 并不是, 我们还可以知道任意两个右侧元素是否在同一连通块, 只不过单用这个信息没办法形成对应关系, 所以在刚刚的构造中没有起作用. 这里有 key motivation: 如果存在且仅存在一个行 (列) 连通块大小为 , 我们可以直接确定某个 , 然后根据 和哪些元素在同一个连通块里确定 这一列 (行) 的集合. 这样, 就算两列 (行) 的长度本来相同, 我们也可以根据特殊元素 来区分它们!
给出对 的构造, 这里以 为例:
( 表示自然数 的后继, 这样表格好看一点.)
仍然在两次实验中分别划分行和列询问. 求答案时, 先根据 "行长为 (只有两行) 且列长为 (另一行上不可能存在列长为 )" 确定 . 然后根据 "和 属于同一行连通块, 列长依次递减" 得到 和 的所有对应. 接着令 "和某个 同属一个列连通块" 的元素列长 , 这样就完全消除了最外圈一行一列的影响, 剩下的就和 一样做了. 加边 次, 询问 次.
怎么办, 越来越喜欢构造题了.
6.「洛谷 P9411」Gtrimee
- Link | 胡.
Para 怎么问了兔一个经典 trick? 原来 Para 又在卷洛谷的比赛. Para AK 了, 比赛 unrated 了, 可喜可贺.
GF 入门训练, 先求出任意有根儿子有序无标号树的 GF (哈哈! 天下谁人不识 Catalan 数?), 则所求树第 层结点的子树 GF 是 , 再进行 次和求 一样的迭代就行. 这里的迭代是
很显然, 令 , 这个迭代一次就是对 的线性变换:
矩阵快速幂即可. . 快速幂的结果也可以直接解出来, 这样是 的.
7.「CF 1500F」Cupboards Jumps ⭐
- Link & Submission.
- 「A.DP-数据结构优化」
感觉兔的思维习惯变得 contructive & mathematical 了, 根本不会做 OI 题. (雾
DP! DP! DP! 好看起见, 原题的 分别换成 . 令 表示构造 使得 合法时, 是否可行. 转移:
注意第三类转移是覆盖性的 "全部合法", 第一类转移是整体位移, 第二类转移只会新增单点. 初始状态 可以表示为一段足够长的区间, 进而我们可以通过维护大区间和小单点的位移来快速实现转移. 利用状态信息反向构造方案即可. .
8.「UR #11」「UOJ #167」元旦老人与汉诺塔
- Link & Submission.
直觉上有种怪异感, 理论上任意两个合法状态都是可达的, 但步数是指数级别, 合法状态的数量也是指数级别, 我们还要计数而非找最优解. 怎么回事呢?
那就只能看 — 如果称 是可接受的 "线性" 级别, 那么真正被移动的盘子就只能是 "对数" 级别.
顺着这个思路发现, 初始状态实际上只有 个盘子是可能被移动的, 暴力记搜的状态空间是 , 当然这只是毛估, 真正有效状态量自然很少, 能过就对啦.
9.「NOI Simu.」高维游走 ⭐
- Private link & Submission.
- 「A.DP-状压/插头 DP」
先不考虑疲倦度, 我们先对一个确定的步数序列 描述答案, 其中 即在第 阶段 (和第 阶段) 的行走步数, 那么这种方案对 的贡献为
这里数的集合运算即对其二进制所表示的集合的运算.
这一基本的性质告诉我们, 我们只需要考虑满足等式右侧真值式的 . 一个 将贡献到 的 . 由于 间两两交集为空这个限制很难在依次枚举 时记录, 我们更倾向于按位考虑贡献. 设 表示第 个 bit 出现在哪个 中, 若未出现则令 . 那么 . 据此, 我们得到了一个暴力做法: 枚举所有可能的 , 统计出现奇数次的 的个数.
都说啦, 我们倾向于按位考虑贡献. 当只考虑 时, 的低 个 bit 已经确定, 此时 剩下的 bit 构成的数在 内, 这就产生了对 的分类标准. 注意, 我们的最终目标是统计 "同一个 出现奇数次" 的数量, 所以这里应该按照 "未确定的长成什么样子" 来划分状态. 设 表示 {此时有多少个 的低 位组合满足: 这低 位能且仅能与集合 中的整数拼出一个存在奇数次的 }. 我们对于当前 bit 可以出现在的位置集合 , 预处理 表示状态 经过可选集合为 的位转移到的新状态, 其中 表示第 位 (转移完成后被确定的位) 是 的状态, 同理. 这样转移可以 完成, 最终复杂度 , 其中 . 预处理也许可以用出色的位运算技巧再优化优化 (啊, 好像不如每次现场算转移哈).
10.「NOI Simu.」过山车 ⭐
- Private link & Submission.
- 「A.图论-网络流-费用流」
虽然鉴定为不如无限之环, 但不可否认这还是一个有点意思的网络流建图.
网格图上的简单环一定是二分的, 借此我们可以扔掉诡异的 "存在可行流" 限制, 转而在二染色后描述 "每个点都和两个异色点配对". 我们要求, 若一个点和它的两个配对点贡献, 则不贡献收益, 否则贡献 的收益. 换换等价表述, 若一个点在横向两个邻接点和纵向两个邻接点里分别选了一个, 才能贡献 的收益. "选得多" 优于 "选得少", 这样就可以描述了:

跑最大费用最大流, 若流量合法, 答案就是最大费用减去 . 复杂度 .
11.「NOI Simu.」木棍 ⭐
- Private link | 不想写 (星星眼.jpg
- 「A.图论-差分约束」
把木棍缩到左端点, 如果 且 , 这就是一个 Hall 定理的事儿. 据此我们也能发现, 把所有端点离散化, 仅考虑区间上 Hall 定理的判据, 仍然是等价的判定.
一维的规划问题, 想想差分约束? 设 表示 之前放置的木棍数量, 那么限制条件形如 . 的确可行. 当 时, 我们就有限制 , 时, 通过 也能描述这些要求, 最后加上前缀和的固有条件 , 跑差分约束即可.
直接 SPFA 最坏 , 可以通过线段树维护整体转移做到 .
12.「UR #11」「UOJ #169」元旦老人与数列 ⭐
- Link & Submission.
- 「A.数据结构-线段树」
Segment Tree Beats!
嗯, 就用这玩意儿维护就行. 为了更方便维护历史最小值, 我们可以把所有修改标记变成 (当前增量, 前缀增量最小值) 这样的数对, 对区间的最小值和其他值需要分别维护不同的标记. .
13.「UR #12」「UOJ #180」实验室外的攻防战
- Link & Submission.
设 在 中出现的位置是 , 在 中出现的位置是 , 显然应当满足 , 有端 (指迅速搓了一发暴力) 猜测这是充要条件, 我们只需要实现快速检查. 若某对 导致非法, 必然有点 在点 的左上方. 三维偏序走一走就行, 只需要检查偏序存在性, .
14.「UR #13」「UOJ #186」Yist
- Link & Submission.
若存在可行的消除方案, 则必然存在一种被删除元素递增的删除方案. 假设某个询问串是 , 那么对于某个 , 它就需要能在序列 中被第一个删除, 也即存在一个以 为最小值的长度为 的子段.
可见, 我们只需要求出每个 对应的最长子段的最小长度就能得到答案. 按值从大到小考虑 的 , 将其加入到序列中暴力向左右扩展, 遇到已经被扩展过的结点直接跳过当前检查 (当前子段不短于曾经扩展这个位置的元素), 这样就 了.
15.「UR #13」「UOJ #187」Ernd ⭐
- Link & Submission.
- 「A.DP-斜率优化」「B.离线」
令 表示你觉得它该表示的东西, 那么 有两类转移:
形如 的限制可以拆成 , 它也描述了点 和点 的偏序关系, 所以前面一个转移可以根据 离线后用 BIT 维护 轴上的偏序贡献解决.
显然, 一列可 combo 的子段在上述离线过程中肯定会被依次取出来, 我们可以在 处转移时顺便将 放入 所在 combo 连续段的凸包上, 在 被拿出来的时候就弹一弹凸包进行第二类转移. 最终复杂度 .
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
2022-06-12 Solution -「CF 590E」Birthday
2020-06-12 Solution -「NOI.AC 省选膜你赛」T2