原神傻逼游戏。
一些话
上一次真正意义上的搞 OI 已经是 2024.10 了。
球球你了起码让我回到初二初三的水平好不好。
题目 \(60 \min\) 还卡就直接跳。
Tricks
- 求一个序列经过邻项对换变成单谷序列的最少操作数。
不妨只考虑大数对小数的贡献,这样便于统计。
对于一个 \(a_i\),考虑其放在“谷”的左边还是右边。这样来分类讨论的话,答案记为 \(a_i\) 左边比它小的值的个数和右边比它小的值的个数的较小值。BIT 可以简单维护。
To Do List
- P16280 题解。
- P15975
- P14031
- CF1542E
进程
P9350 [JOI 2023 Final] 宣传 2 / Advertisement 2
评级:普及/提高-。
用时:\(45 \min\)。
拆绝对值,而后有两条限制,直接排序枚举即可。
P14332 [JOI2021 预选赛 R2] 活动巡游 / Event Hopping
评级:普及/提高-。
用时:\(60 \min\)。
分成在当前城镇和不在当前城镇两个部分 dp,对于后者二分转移即可。
P11663 [JOI 2025 Final] 勇者比太郎 2 / Bitaro the Brave 2
评级:普及/提高-。
用时:\(45 \min\)。
二分初始力量,check 里面写个简单的前后缀判断即可。
P7804 [JOI Open 2021] 决算报告 / Financial Report
评级:提高。
用时:\(120 \min\)。
有一个非常显而易见的转移:
关键在于如何求 \(sub(i)\)。
我们按 \(a_i\) 排序,而后从小到大将其下标插入 std :: set。不难发现若 \(j \in sub(i)\) 当且仅当在 std :: set 中 \(i, j\) 相差不超过 \(D\)。
在此之上,线段树维护转移即可。
P11202 [JOIG 2024] 名前 / Name
评级:提高+/省选-。
用时:\(240 \min\)。
对于 \(K\) 这个条件而言,考虑逐步限制。
- 对于 \(K = 0\):记 \(dp_{i, j}\) 表示已经考虑到 \(S_i, T_j\) 的最短长度,是一个经典的双序列 dp。
- 对于 \(K = 1\):记 \(dp_{i, j, c_1}\) 表示已经考虑到 \(S_i, T_j\) 且答案串的末尾为 \(c_1\) 的最短长度。转移时对于一个字符 \(c\) 判断其是否能转移,该步也是平凡的。
- 对于 \(K = 2, 3\),同理知在状态后面额外添加答案串的末尾字符即可。
当 \(K = 3\) 时上述状态设计复杂度最劣,为 \(O(n ^2 |\Sigma| ^3)\)。
对于这个状态进行观察,我们发现可以将末尾字符简单的归成四类:
- 占位符,对后续状态没有限制。
- 匹配 \(S_i\)。
- 匹配 \(T_j\)。
- \(S_i, T_j\) 都匹配。
进而分析可知,同一种类的字符转移方式时相似的。
基于该分析,我们可以优化状态:记 \(dp_{i, j, x, y, z}\) 表示已经考虑到 \(S_i, T_j\) 且答案串的末尾字符种类分别为 \(x, y, z\) 的最短长度。
转移可以简单的按是否为占位符分个类,自然是好写的。
重点在于判断非占位符是否能转移,记录状态中 \(S, T\) 的偏离步数即可。
P12458 [JOI2025 预选赛 R2] 冰淇淋 / Softcream
评级:普及+/提高-。
用时:\(60 \min\)。
题意转化为求:
显然 \(c_k\) 最大或最小时取到答案,式子进一步化为:
不难发现 \(b_j\) 取绝对值内两式和一半的相反数上式取答案,简单二分即可。
P17089 掷出重围
评级:普及+/提高-。
用时:\(120 \min\)。
小观察:按 \(w_i\) 排序后投球一定不劣。
于是设 \(dp_{i, j, k}\) 表示前 \(i\) 物品,当前背包容量为 \(j\),最大价值为 \(k\) 的总贡献。
对于物品 \(i\) 的转移,按其是否大于现在的 \(k\) 分类转移,具体地:
- 若 \(w_i > k\),\(dp_{i, j, k} \to dp_{i + 1, j + x_i, w_i}\)。
- 否则 \(dp_{i, j, k} \to dp_{i + 1, j + x_i, k + 1}\)。
离散化 \(w_i\) 即可。
P10206 [JOI 2024 Final] 建设工程 2 / Construction Project 2
评级:普及+/提高-。
用时:\(30 \min\)。
枚举一条边 \((u, v)\),重连这条边合法的条件为:
枚举一维维护一维即可。
P14799 [JOI 2026 二次预选] 比太郎之旅 3 / Bitaro's Travel 3
评级:普及+/提高-。
用时:\(30 \min\)。
注意到路径起点一定是奇数且奇偶性和步数相关,直接拆点为奇数点和偶数点即可。
P14798 [JOI 2026 二次预选] 购物 3 / Shopping 3
评级:普及+/提高-。
用时:\(60 \min\)。
直接二分 \(k\),可以对 \(a\) 序列分为两段算贡献,这个可以二分查找第一个大于 \(k \times d_j\) 的位置。
容易发现这个序列的贡献函数是一个下凸壳,其导函数斜率是单调递增的,在其上面二分即可。
P15823 [JOI Open 2013] 观影 / Watching
评级:普及+/提高-。
用时:\(120 \min\)。
\(w\) 越大,所需相机数量不减,可以对 \(w\) 二分。
这里的一个有效状态是形如 \((i, j, k)\) 形式的,表示到了第 \(i\) 个活动地点,使用了 \(j\) 个小型相机和 \(k\) 个大型相机。
可是这样设计状态无法进行有效的判断,不妨将可行性问题转换为最优化问题重新设计:记 \(dp_{i, j}\) 表示到了第 \(i\) 个活动地点,使用了 \(j\) 个小型相机所需的大型相机数,则最后只需检查 \(dp_{n, p}\) 是否大于 \(q\) 即可。
P16255 [DSTOI Round 0] 白石溪
评级:普及+/提高。
用时:\(60 \min\)。
划分序列的问题自然的想到 dp。题目中的两个限制框定了转移范围,轻松转移即可。
P15797 【MX-J28-T4】「Cfz Round 8」Color Problem
评级:提高+/省选。
用时:\(180 \min\)。
考虑如何设计状态转移才是完备的。需要知道当前在第几列,连通块大小和前几列的状态。基于该分析,我们得知让连通块所占的信息越少对我们而言是越有利的。所以可以设计 \(dp_{i, j, S}\) 表示第 \(i\) 当前连通块大小为 \(j\) 前面状态为 \(S\) 的染色方案。额外设计 \(f_i\) 表示连通块大小不超过 \(i\) 的染色方案数。这样答案是便于统计的,为:
另外考虑状态之间的转移即可。这个可以较为简单的手模出来。
P16812 [蓝桥杯 2026 国 Python A] 压缩字符串
评级:提高。
用时:\(240 \min\)。
首先发现可以按 # 分段。不妨设第 \(i\) 段长度为 \(j\) 的字符串方案为 \(res_{i, j}\),那么答案实际上是对 \(res_{i, j}\) 做背包。
再来考虑段内的问题,其本质为求本质不同子序列方案数,直接求解即可。
P15289 「YLLOI-R3-T4」止战之殇
评级:普及+/提高。
用时:\(90 \min\)。
考虑求出两个怪兽之间最多能待几个回合,基于此一直向左跳到头再往右或向右跳到头再往左即可。
细节很多,考虑直接拼四个贪心上去。()
P15278 [MCO 2025] Subsequence
评级:提高。
用时:\(120 \min\)。
很弱智的 ds 优化 dp,感觉我初二就能做。
P15267 「UTOI 1B」Chaotic Time Trio
评级:普及+/提高-
用时:\(100 \min\)
不难发现无解的情况:
- \(\{0, 0 \}\)。
- \(\{ 0, 0, 0 \}\)。
- \(\{ x(x > 0) \}\)。
- \(\{ 0, x(x > 0) \}\)。
- \(\{ x, y, z(x, y, z > 0) \}\)。
排除这些情况后,可以这样构造:
- 钦定一个 \(x(x > 0)\)。
- 将集合中 \(x\) 以外的数插入集合中,每次取最大值与次大值合并。
- 可以证明最后答案为 \(0\)。
corner case:全 \(0\) 或全 \(x(x > 0)\) 序列可以先合并两项。
P14982 [USACO26JAN1] Supervision G
评级:提高。
用时:\(150 \min\)。
对教练 dp,转移为:
一个学员对教练的贡献是一段区间,这样我们维护区间乘法,区间求和即可。
P15059 [UOI 2023 II Stage] Product
评级:提高。
用时:\(100 \min\)。
很经典的题。钦定 \(a_i\) 为次小值,st 表 + 二分可以确定最大值位置。
知道了最小值和次小值位置之后可以继续 st 表 + 二分去扩展最长的区间。
P14981 [USACO26JAN1] Milk Buckets G
评级:提高。
用时:\(20 \min\)。
考虑阶段二的贪心:假设已经确定了合并顺序序列 \(a\),其贡献为:
可知从小到大填 \(a_i\) 上式最大。
再回来考虑阶段一:如何确定序列的最后形态。注意到第 \(i\) 次合并只要与第 \(i - 1\) 次合并相邻即可,那么就是对于一个递增的填数顺序,只要保证第 \(i\) 次填数放在第 \(i - 1\) 次填数的左右即可。这是一个单谷序列。
问题转化为上文的 Tricks 中的单谷序列内容。
P14969 They'll lead me to you
评级:提高。
用时:\(60 \min\)。
枚举 \(\operatorname{mex}\),序列划分为若干个不含 \(\operatorname{mex}\) 的区间,把这些询问挂在端点上即可。至于贡献的计算,可以用 BIT 轻松维护。
P15360 「WYZOI R2」烟花
评级:普及+/提高-
用时:\(105 \min\)。
模型是子序列 dp,难点在于 check 是否能转移。
注意到竖直距离不超过 \(d\) 这个条件可以转化为斜率区间,将枚举点上下平移算区间范围即可。
P16280 「MierOI R1」Eternal
评级:提高。
用时:\(120 \min\)。
考虑刻画区间形态,一定是一个极大区间左右端点包着几个小区间状物。
维护前缀状态和后缀状态,枚举一个断点,这样就可以统计出一个区间的信息了,而后是一个简单的子序列 dp。
ABC - E - Battles in a Row
评级:普及。
用时:\(3 \min\)。
可行性转最优性:\(dp_{i, j}\) 表示第 \(i\) 个怪剩余生命值为 \(j\) 的最少魔力值花费。
ABC - E - Maximum Glutton
评级:普及+/提高。
用时:\(5 \min\)。
可行性转最优性:\(dp_i\) 表示甜度为 \(i\) 时的最小咸度。
ABC - F - Must Buy
评级:普及+/提高。
用时:\(60 \min\)。
前后缀背包,钦定 \(i\) 的取舍以判断它的必要性。
ABC - F - Sensor Optimization Dilemma
用时:\(45 \min\)。
评级:普及+/提高-。
注意到枚举一种传感器的使用数量可以计算另一种的使用数量。记 \(dp_{i, j}\) 表示覆盖完前 \(i\) 段需要使用 \(j\) 个 \(1\) 类型传感器。而后枚举一个 \(k\) 作为第 \(i\) 段的使用数量,而后直接转移即可。
ABC - E - Warp
记 \(dp_{i, j, k}\) 表示方案 \(1, 2, 3\) 分别用了 \(i, j, k\) 次。std :: set 判掉障碍点即可。
ABC - E - Subarray Sum Divisibility
用时:\(45 \min\)。
评级:普及+/提高-。
发现序列的最终态一定是 \(a_i\) 与 \(a_{i + L}\) 同余,可以预处理出 \(val_{i, j}\) 表示模 \(L\) 为 \(i\) 的位置模 \(m\) 为 \(j\),背包合并这一坨即可。
ABC - F - Monochromatic Path
用时:\(45 \min\)。
评级:普及+/提高-。
注意到对一行或一列进行大于一次操作是无意义的,因此我们定义 \(dp_{i, j, x, y}\) 表示走到点 \((i, j)\) 且第 \(i\) 行第 \(j\) 列是否被操作的最小费用。显然第 \(i\) 行能被操作的条件是第 \(i - 1\) 行的同列元素与其颜色相反。对于列同理。如此转移即可。
ABC - E - Don't Isolate Elements
用时:\(45 \min\)。
评级:普及+/提高-。
假如我们要考察第 \(x\) 行是否合法,我们需要得知第 \(x - 1. x +1\) 行的信息才能判断。依此设计 \(dp_{i, x, y}\) 表示到第 \(i\) 行且已经确定了前 \(i - 1\) 行且第 \(i\) 行是否被操作,第 \(i - 1\) 行是否被操作的合法的最小操作数。转移时枚举 \(i - 1\) 的 dp 状态即可。
ABC - G - AtCoder Tour
用时:\(45 \min\)。
评级:普及+/提高-。
考虑最后的答案形式,一定是走到某一个点并且一直待着不在走动的形式。而从起点到任意一个点所走动的距离一定不超过 \(n \times m\) 步。因此设 \(dp_{i, j, k}\) 表示到点 \((i, j)\) 走了 \(k\) 步的最大乐趣值(不加等待时间)。随便转移即可。
ABC - F - Shortcuts
用时:\(45 \min\)。
评级:普及+/提高-。
一个经典的序列划分 dp。观察到至多跳过 \(O(\log V)\) 个点,因此只需要 \(O(\log V)\) 枚举上一位,\(O(\log V)\) 判断合法性即可。
ABC - F - Prefix LIS Query
用时:\(45 \min\)。
评级:普及+/提高-。
注意到询问 \(X_i\) 对我们的限制是最紧的,于是我们离线后用按值从小到大插入,线段树转移即可。
ABC - F - |LIS| = 3
用时:\(45 \min\)。
评级:普及+/提高-。
因为合法序列的 LIS 长度不超过 \(3\),且观察到值域不超过 \(10\)。所以不妨设 \(dp_{i, x, y, z}\) 表示已经填完前 \(i\) 位,当前合法的 LIS 是 \((x, y, z)\) 的情况。转移只需枚举一个数 \(w\) 替换 \((x, y, z)\) 中的一个即可。
ABC - F - Simple Operations on Sequence
用时:\(90 \min\)。
评级:普及+/提高-。
是一个经典题。考虑往已选集合里面添加一个单点的代价即可。
DP - V - Subtree
用时:\(90 \min\)。
评级:普及+/提高-。
设计 \(\operatorname{sub}(x)\) 和 \(U \backslash \operatorname{sub}(x)\) 的状态,换根时发现贡献是形如排除 \(\operatorname{sub}(x)\) 中的某个点,前后缀优化即可。
G - Vertex Deletion
用时:\(45 \min\)。
评级:普及+/提高-。
结论是最大匹配等于总点数减最大独立集,问题转化为树上最大独立集。
ABC - F - Treasure Hunting
用时:\(45 \min\)。
评级:普及+/提高-。
考虑钦定 \(a_{x, y}\) 为第 \(K\) 大整数,设 \(dp_{i, j, k}\) 表示走到点 \((i, j)\),选完了前 \(k\) 大整数的最小代价。转移比较 navie。
ABC - G - Divide a Sequence
用时:\(45 \min\)。
评级:普及+/提高-。
可以分成两个部分分别 dp,单调栈转移即可。
ABC - F - Two Exams
用时:\(45 \min\)。
评级:普及+/提高-。
很舒服的题目,根据偏序关系转移即可。
ABC - E - RLE
用时:\(45 \min\)。
评级:普及+/提高-。
设 \(dp_{i, j}\) 表示前 \(i\) 位替换成长度为 \(j\) 的字符串的方案数,有转移:
其中 \(f(len)\) 表示 \(len\) 在十进制下的位数。
发现 \(f(len)\) 只有 \(4\) 种取值,对于每一种转移前缀和即可。
ABC - G - Pre-Order
用时:\(45 \min\)。
评级:普及+/提高-。
简单区间 dp。对于右子树新建虚拟节点即可。
P13009 【MX-X13-T4】「KDOI-12」好胜是人的本能,功利是社会的本性。
用时:\(45 \min\)。
评级:普及+/提高-。
注意到至多只会操作 \(2\) 次,于是可以设 \(dp_{i, j}\) 表示到第 \(i\) 位且第 \(i\) 位操作了 \(j\) 次的最小操作数。
P13010 【MX-X13-T5】「KDOI-12」茫茫人海如都市的晚高峰,迎面的车终将相遇,迎面的车终将分别。
用时:\(45 \min\)。
评级:提高。
注意到调配的约束随着最大负载量的减少而加紧,所以我们可以二分最大负载量,模拟分配车道的过程即可。
P14378 【MX-S9-T1】「LAOI-16」签到
用时:\(45 \min\)。
评级:提高。
首先原序列可以变为一个新序列,对新序列排序。对于一个修改,找到其在新序列上的位置,序列被分为三段,对于每一段简单算一下贡献即可,可以画图模拟一下。
P13732 【MGVOI R1-D】图上的数(graph)
咕一下。
P13562 「WWOI R1」WsW 的田地
用时:\(45 \min\)。
评级:提高。
对于差分数组随机赋权哈希即可。
Div. 1 C. XOR Inverse
用时:\(45 \min\)。
评级:提高。
对原序列建出 01 trie,那么 01 trie 上保证了 \(a_i < a_j\) 的偏序,我只要统计横跨左右子树的逆序对即可。
Div.2 E. Marbles
用时:\(45 \min\)。
评级:提高。
可以预处理出一个颜色挪到一个颜色集合前面的代价,而后 dp 即可。
Div. 2 D. Hot Start Up
D1
用时:\(30 \min\)。
评级:普及+/提高-。
设 \(dp_{i, j}\) 表示两个 CPU 分别以 \(a_i, j\) 结尾的代价,分类转移。
D2
用时:\(45 \min\)。
评级:提高。
压维后,转移可视作全局加,单点修改,前缀查询。线段树维护即可。
VK CUP C. Monsters
题目转化为维护一个首项、公差为 \(1\) 的等差数列。
这个可以挂到值域线段树上维护。
Div. 2 E. AND-MEX Walk
一个重要的观察:答案不超过 \(2\)。
对于答案分别为:\(0, 1, 2\) 的情况分别考察,可以按位维护并查集。这样答案的取值可以用并查集的连通性统计出来。
Div. 1 + Div. 2 D. New Year and Conference
本质上还是偏序的套路,枚举左端点维护右端点即可。
Div. 1 B. A Lot of Games
建出 Trie,叶子节点是必败态。跟据这个可以推出其它节点的可胜态和可败态。
Div. 1 C. Limited Edition Shop
按照原顺序是不好做的,考虑按 Alice 顺序做。
设计 \(dp_{i, j}\) 表示按该顺序 Alice选完前 \(i\),Bob 选了 \(j\) 个的代价。记 \(pos_i\) 表示 Bob 对应的 Alice 的下标,有刷表转移:
一个全局加一个单点修,线段树维护转移即可。
Div. 2 E. A Trivial String Problem
简单的 Border dp。
Div. 2 E. Predicting Popularity
维护一棵值域线段树,线段树维护 \(\max(a_i - ac, 0) + \max(d_i - dr, 0)\) 的值。每次修改相当于后缀加,查询则是在线段树上查询第一个 \(\max(a_i - ac, 0) + \max(d_i - dr, 0) \geq i\) 的位置,线段树上二分即可。
Div. 1 C. Revival
限制从后往前逐步加紧,不妨倒序确定元素。这样是可以二分出当前元素的,至于判重,使用并查集即可。
Div. 2 E1. Looking at Towers (easy version)
\(L(h), R(h)\) 的交一定是 \(\max h_i\)。因此先求出 \(L(h), R(h)\),在位置 \(x(h_x = \max h_)\) 进行决策,就是一个简单的双序列 dp。
Div. 2 E. Simons and Dividing the Rhythm
划分序列 dp。设计 \(dp_i\) 表示前 \(i\) 位操作后得到的新字符串方案数。但是这样做是要去重贡献的。我们思考问题的最小子问题:若一个区间被翻转,其任意子区间没有除翻转该区间的其他方案到达该翻转状态,则这个区间的翻转贡献有且仅有这一次。我们称这种区间为最短合法区间
那么我们可以更改状态设计:\(dp_i\) 表示前 \(i\) 位只翻转最短合法区间所得新字符串方案数。记区间 \([l, r]\) 的最长 border 的长度为 \(\pi_{[l, r]}\),则区间为最短合法区间当且仅当 \(\pi\) 值为 \(0\)。
Div. 1 B. Strange Definition
当且仅当 \(x \times y\) 为完全平方数时 \(K\) 为完全平方数。
那么对于一个 \(x\),将其唯一分解为 \(\prod p_k ^ {c_k}\) 的形式,令 \(S\) 为满足 \(2 \nmid c_k\) 的 \(k\) 的集合,那么统计每一个 \(x\) 的 \(\prod_{k \in S} p_k\) 即可,记这个值为 \(\operatorname{val}(x)\)。
由于相邻的数操作后会变为它们的乘积,因此只有操作一次或不操作是有效的。
对于不操作的部分,答案为 \(\operatorname{val}(x)\) 出现次数的最大值。
对于操作一次的部分,答案为 \(\operatorname{val}(x) = 1\) 的出现次数加 \(\operatorname{val}(x)\) 的出现次数整除 \(2\) 的出现次数之和。
Div. 3 G. Strange Beauty
排序后是一个子序列 dp,按值域记录 dp 即可 \(O(n \sqrt n)\) 做。
Div. 1 B. Nezzar and Binary String
倒着做,线段树模拟即可。
Div. 2 D. Sum of Paths
你可以轻易 dp 出 \(a_i\) 贡献了几次。
Div. 1 D. Strange Housing
直接黑白染色即可。
Div. 2 E. Minimum Path
由于 dijkstra 是基于贪心实现的,我们可以直接建出分层图跑最短路。
Технокубок F. Useful Edges
首先有一种显然的 \(O(mQ)\) 复杂度的做法。
枚举一条边,check 其断掉之后的贡献是否合法:\(dis_{x, u} + w + dis_{v, y} \le l\)。
其中 \((u, v, w)\) 为原图上的一条边,\((x, y, l)\) 为一组询问。
运用偏序问题中常用的“枚举一维维护一维”的思想,我们不妨只枚举一个询问的其中一个端点 \(x\)。
围绕我们枚举的 \(x\),可以将上述式子化为:
此时左边式子的值因为已经枚举了,所以能轻松算出来,相当于一个定值。我们只需要让这个定值小于右边式子的最大值即可。
所以,当前问题转化为求 \(l - dis_{v, y}\) 的最大值。注意到 \(l, y\) 是同时枚举的(同属一个询问),那么在此基础上再枚举点 \(v\) 就能算出该值。
再来考察复杂度。check 式子 \(O(nm)\),预处理 \(O(nQ)\),总时间复杂度 \(O(n(m + Q))\)。
ABC - F - Road Blocked
倒着做,新增一条边可以 Floyd \(O(n)\) 添加贡献。
ABC - E - Development
机场点可以连虚点。
P14379 【MX-S9-T2】「LAOI-16」摩天大楼
刻画答案形态,是形如不含 \(1\) 的子段或者含 \(1\) 不含 \(2\) 的子段。利用 std :: set 可以轻松维护。
Div. 2 G. Xor-MST
建出 01 Trie。经过的重复路径是没有贡献的,换而言之,我们只需要对于一个节点统计其横跨左右子树的贡献即可。我们可以自上而下地合并,相当于是一个延迟决策的操作。
Div. 2 E. Chaotic Merge
考虑我们只需求 \(f(1, |x|, 1, |y|)\) 怎么做。设计 \(dp_{i, j, k}\) 表示 \(x\) 串选完前缀 \(i\),\(y\) 串选完前缀 \(j\),上一次选的是 \(x\) 串还是 \(y\) 串的数量。可以直接转移。答案是 \(dp_{|x|, |y|, 0} + dp_{|x|, |y|, 1}\)。
现我们要求所有子段的 \(f\) 值之和,那么我们可以钦定一个起点 \((i, j)\)。落实到代码中就是状态 \((i, j)\) 的初始值设为 \(1\)。为了避免算重,我们可以在 \(dp\) 中再维护一个维度 \(S\) 表示 \(x, y\) 串是否被选过。状态转移还是类似于下一位选 \(x\) 串和选 \(y\) 串的贡献统计。
实现采用刷表会更为简便。
Div. 2 F. Comfortably Numb
结构很容易让人联想到笛卡尔树。我们需要保证插入、删除的复杂度,只需要在分治的时候把较短区间的异或前缀和插入 01 Trie,并在通过笛卡尔树的一条轻边的时候清空即可。

浙公网安备 33010602011771号