Live2D

Solution Set - “伸手向着拉格朗日点作别”

Defining LATEX macros

  Umm… UOJ 浓度极高的一个 sol set. 摘的标题和上一个 sol set 是姊妹篇!

0.「UR #9」「UOJ #133」电路手动分析

  二分答案, 尽量把选择的结点排成正方形, 计算边数够不够. O(logmin{nm,r}).

1.「UR #9」「UOJ #134」App 管理器

  枚举未定向边 (u,v), 检查去掉这条边后是否存在 uvvu 的路径, 二者中至少存在一个, 据此定向即可. O(m2).

2.「UR #10」「UOJ #152」汉诺塔

  你这 106 的操作限制是来骗人的还是来骗兔的?

  如何利用 2,3 两根空柱子? 把 1 柱子上的盘子依次取出放入 2,3 之一的过程可以看作对 1 柱子序列的一个划分, 结合排序的目标, 那么自然想到上升/下降子序列. 假设 1 从上到下读可以划分为 k 个连续的上升子段, 我们就可以把它们倒到 2,3 上, 在两根柱子上各形成 k/2 个下降子段. 每次取出两个柱子最顶上的子段归并回 1, 子段数量 ÷2. 因此 O(logn) 次迭代后必然完成排序. 操作次数 O(nlogn).

3.「UNR #2」「UOJ #312」梦中的题面 ⭐

  数位 DP? 啊, 数位 DP!

  在 c=1 时, xi 就是 b 进制下的任意 i 位数, 由于 mb 进制数的加法在某一位上的总进位不超过 m, 我们可以暴力记录仅考虑低若干位时, xin 在当前位的值. 对 c=0, 直接新增一维状态记录有多少个在当前位可以非 0 (而非留到最高位变成 xi=bi) 即可. 最后的状态就是 f(i,j,k) 表示考虑了第 i 位, 有 j 个数可以自由填位, 当前位 xin=k[1,m] 的方案数. 直接转移可以做到 O(m4b). 如果从高位向低位 DP 可以得到四方做法, 不过写着比较麻烦.

4.「NOI Simu.」战舰

  横纵坐标上的操作相对独立, 我们可以对每一个横坐标维护其一列上的信息, 纵坐标同理. 移动什么的可以直接合并坐标, 加法和查询按照行列长度根号平衡就行了. O(mn). 可能有一些很 dirty 的实现细节.

5.「UR #10」「UOJ #153」世界线 ⭐

  对于左侧的下标集合 S, 我们尝试找到其在右侧对应的集合 {aiiS}. 我们可以把左侧连成若干个大小两两不等的连通块, 再在右侧询问出每个连通块, 这样就能根据连通块大小得到对应关系. 为了得到更确定的对应, 自然的 motivation 就是尝试让左侧集合大小两两不同. 我们可以将左侧标号分组:

4321112233456478910

可以发现, 左侧的行长度和上侧的列长度构成的坐标可以唯一确定一个单元, 我们就能根据右侧集合所在的行列长度信息直接得到答案.

  这个构造只在 n=k(k+1)/2 时适用, 当 nk(k+1)/2, 我们不可能让行列长度都两两不等, 怎么办呢?

  反思一下, 连通块询问带给我们的信息只有 "连通块大小"? 并不是, 我们还可以知道任意两个右侧元素是否在同一连通块, 只不过单用这个信息没办法形成对应关系, 所以在刚刚的构造中没有起作用. 这里有 key motivation: 如果存在且仅存在一个行 (列) 连通块大小为 1, 我们可以直接确定某个 ap, 然后根据 ap 和哪些元素在同一个连通块里确定 p 这一列 (行) 的集合. 这样, 就算两列 (行) 的长度本来相同, 我们也可以根据特殊元素 ap 来区分它们!

  给出对 n=k(k+1)/2+r (r0) 的构造, 这里以 n=13 为例:

432111122334564789103111213

(k=k+1 表示自然数 k 的后继, 这样表格好看一点.)

  仍然在两次实验中分别划分行和列询问. 求答案时, 先根据 "行长为 r (只有两行) 且列长为 1 (另一行上不可能存在列长为 1)" 确定 an. 然后根据 "和 an 属于同一行连通块, 列长依次递减" 得到 nr+1nanr+1n 的所有对应. 接着令 "和某个 ai (i[nr+1,n]) 同属一个列连通块" 的元素列长 1, 这样就完全消除了最外圈一行一列的影响, 剩下的就和 r=0 一样做了. 加边 2×O(n) 次, 询问 2×O(nn) 次.

  怎么办, 越来越喜欢构造题了.

6.「洛谷 P9411」Gtrimee

  Para 怎么问了兔一个经典 trick? 原来 Para 又在卷洛谷的比赛. Para AK 了, 比赛 unrated 了, 可喜可贺.

  GF 入门训练, 先求出任意有根儿子有序无标号树的 GF F(z) (哈哈! 天下谁人不识 Catalan 数?), 则所求树第 k 层结点的子树 GF 是 F(z)1, 再进行 k 次和求 F(z) 一样的迭代就行. 这里的迭代是

F(z)=z1F(z).

很显然, 令 F(z)=P(z)/Q(z), 这个迭代一次就是对 [P(z)Q(z)]T 的线性变换:

[P(z)Q(z)]=[z11][P(z)Q(z)].

矩阵快速幂即可. O(nlognlogk). 快速幂的结果也可以直接解出来, 这样是 O(nlogn) 的.

7.「CF 1500F」Cupboards Jumps ⭐

  感觉兔的思维习惯变得 contructive & mathematical 了, 根本不会做 OI 题. (雾

  DP! DP! DP! 好看起见, 原题的 h,w 分别换成 a,b. 令 f(i,j) 表示构造 a[:i] 使得 b[:i2] 合法时, |aiai1|=j 是否可行. 转移:

f(i+1,bi1j)f(i,j)(j<bi1),f(i+1,bi1)f(i,j)(j<bi1),f(i+1,k)f(i,j)(j=bi1,kbi1).

注意第三类转移是覆盖性的 "全部合法", 第一类转移是整体位移, 第二类转移只会新增单点. 初始状态 f(0,)=T 可以表示为一段足够长的区间, 进而我们可以通过维护大区间和小单点的位移来快速实现转移. 利用状态信息反向构造方案即可. O(nlogn).

8.「UR #11」「UOJ #167」元旦老人与汉诺塔

  直觉上有种怪异感, 理论上任意两个合法状态都是可达的, 但步数是指数级别, 合法状态的数量也是指数级别, 我们还要计数而非找最优解. 怎么回事呢?

  那就只能看 m — 如果称 m 是可接受的 "线性" 级别, 那么真正被移动的盘子就只能是 "对数" 级别.

  顺着这个思路发现, 初始状态实际上只有 3log2m 个盘子是可能被移动的, 暴力记搜的状态空间是 O(m33log2m)=O(m1+3log23), 当然这只是毛估, 真正有效状态量自然很少, 能过就对啦.

9.「NOI Simu.」高维游走 ⭐

  先不考虑疲倦度, 我们先对一个确定的步数序列 {am} 描述答案, 其中 ai 即在第 0 阶段 (和第 i 阶段) 的行走步数, 那么这种方案对 f() 的贡献为

(t0{an})i=1n(tiai)[ij, aiaj=][i, ai(tit0)](mod2).

这里数的集合运算即对其二进制所表示的集合的运算.

  这一基本的性质告诉我们, 我们只需要考虑满足等式右侧真值式的 {an}. 一个 {an} 将贡献到 x=iiaif(x). 由于 {an} 间两两交集为空这个限制很难在依次枚举 ai 时记录, 我们更倾向于按位考虑贡献. 设 pi 表示第 i 个 bit 出现在哪个 a 中, 若未出现则令 pi=0. 那么 x=ipi2i. 据此, 我们得到了一个暴力做法: 枚举所有可能的 {pw}, 统计出现奇数次的 x 的个数.

  都说啦, 我们倾向于按位考虑贡献. 当只考虑 {p0..k1} 时, x 的低 k 个 bit 已经确定, 此时 x 剩下的 bit 构成的数在 [0,m] 内, 这就产生了对 x 的分类标准. 注意, 我们的最终目标是统计 "同一个 x 出现奇数次" 的数量, 所以这里应该按照 "未确定的长成什么样子" 来划分状态. 设 f(k,S) 表示 {此时有多少个 x 的低 k 位组合满足: 这低 k 位能且仅能与集合 S[:2m1] 中的整数拼出一个存在奇数次的 x}. 我们对于当前 bit 可以出现在的位置集合 T{0,1}m, 预处理 (S,T)(R0,R1) 表示状态 S 经过可选集合为 T 的位转移到的新状态, 其中 R0 表示第 k 位 (转移完成后被确定的位) 是 0 的状态, R1 同理. 这样转移可以 O(1) 完成, 最终复杂度 O(m222m)O(w2m), 其中 w=logV=31. 预处理也许可以用出色的位运算技巧再优化优化 (啊, 好像不如每次现场算转移哈).

10.「NOI Simu.」过山车 ⭐

  虽然鉴定为不如无限之环, 但不可否认这还是一个有点意思的网络流建图.

  网格图上的简单环一定是二分的, 借此我们可以扔掉诡异的 "存在可行流" 限制, 转而在二染色后描述 "每个点都和两个异色点配对". 我们要求, 若一个点和它的两个配对点贡献, 则不贡献收益, 否则贡献 ai,j 的收益. 换换等价表述, 若一个点在横向两个邻接点和纵向两个邻接点里分别选了一个, 才能贡献 ai,j 的收益. "选得多" 优于 "选得少", 这样就可以描述了:

graph.png

跑最大费用最大流, 若流量合法, 答案就是最大费用减去 iai. 复杂度 O(Dinic(5nm,9nm)).

11.「NOI Simu.」木棍 ⭐

  • Private link | 不想写 (星星眼.jpg
  • 「A.图论-差分约束」

  把木棍缩到左端点, 如果 m=0k=1, 这就是一个 Hall 定理的事儿. 据此我们也能发现, 把所有端点离散化, 仅考虑区间上 Hall 定理的判据, 仍然是等价的判定.

  一维的规划问题, 想想差分约束? 设 si 表示 i 之前放置的木棍数量, 那么限制条件形如 srsl1x. 的确可行. 当 k1 时, 我们就有限制 si+ksi1, m0 时, 通过 syisxi1ci 也能描述这些要求, 最后加上前缀和的固有条件 sisi1, 跑差分约束即可.

  直接 SPFA 最坏 O(n3), 可以通过线段树维护整体转移做到 O(n2logn).

12.「UR #11」「UOJ #169」元旦老人与数列 ⭐

  Segment Tree Beats!

  嗯, 就用这玩意儿维护就行. 为了更方便维护历史最小值, 我们可以把所有修改标记变成 (当前增量, 前缀增量最小值) 这样的数对, 对区间的最小值和其他值需要分别维护不同的标记. O(nlog2n).

13.「UR #12」「UOJ #180」实验室外的攻防战

  设 xa 中出现的位置是 px, 在 b 中出现的位置是 qx, 显然应当满足 x<y, px<pyqx<qy, 有端 (指迅速搓了一发暴力) 猜测这是充要条件, 我们只需要实现快速检查. 若某对 (x,y) 导致非法, 必然有点 (px,qx) 在点 (py,qy) 的左上方. 三维偏序走一走就行, 只需要检查偏序存在性, O(nlogn).

14.「UR #13」「UOJ #186」Yist

  若存在可行的消除方案, 则必然存在一种被删除元素递增的删除方案. 假设某个询问串是 {sn}, 那么对于某个 si=0, 它就需要能在序列 {ajsj=1ajai} 中被第一个删除, 也即存在一个以 ai 为最小值的长度为 x 的子段.

  可见, 我们只需要求出每个 ai 对应的最长子段的最小长度就能得到答案. 按值从大到小考虑 si=0ai, 将其加入到序列中暴力向左右扩展, 遇到已经被扩展过的结点直接跳过当前检查 (当前子段不短于曾经扩展这个位置的元素), 这样就 O(nq) 了.

15.「UR #13」「UOJ #187」Ernd ⭐

  令 f(i) 表示你觉得它该表示的东西, 那么 f(i) 有两类转移:

f(i)maxf(j)+1(|aiaj|bibj),f(i)maxf(k)+(ij+1)2(|ajak|bjbk,[j,i] is combo-able).

  形如 |aiaj|bibj 的限制可以拆成 aiajbibjajaibibj, 它也描述了点 (biai,bi+ai) 和点 (bjaj,bj+aj) 的偏序关系, 所以前面一个转移可以根据 biai 离线后用 BIT 维护 y 轴上的偏序贡献解决.

  显然, 一列可 combo 的子段在上述离线过程中肯定会被依次取出来, 我们可以在 j 处转移时顺便将 (j,max{f(k)}+(j1)2) 放入 j 所在 combo 连续段的凸包上, 在 i 被拿出来的时候就弹一弹凸包进行第二类转移. 最终复杂度 O(nlogn).

posted @   Rainybunny  阅读(200)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
历史上的今天:
2022-06-12 Solution -「CF 590E」Birthday
2020-06-12 Solution -「NOI.AC 省选膜你赛」T2
点击右上角即可分享
微信分享提示