USACO January 2023 铂金组 试题翻译 + 题解 合辑

· · 个人记录

翻译

Problem A

数轴上有 n 个区间 [l_i,r_i],满足 l_1 < l_2 <\cdots < l_nr_1 < r_2 <\cdots < r_n。考虑构造一张无向图,顶点分别代表这 n 个区间,两点间连边当且仅当对应区间相交。在这些区间中,有一些区间是特别的,开始时给定每个区间是否是特别的。接下来你需要回答 q 次询问,每次询问给定两个区间,你需要回答出:

保证 n,q\leq 2\times 10^5

Problem B

游戏中有 n 个据点,你需要在这些据点刷一些金币。一开始的时候,每个据点什么都没有。在接下来的时间内,据点 i 会以每秒 m_i 个金币的速度产生金币。据点之间有若干单向道路,第 i 条道路从 a_i 出发到达 b_i,你需要花费 t_i 秒的时间通行。你可以从任意据点开始,每次经过某个据点时可以获取它之前产生的所有金币。这里认为获取金币的过程不耗费时间。

你需要回答 q 次询问,每次询问给定一个时间节点 s 以及一个终止据点 e。你需要计算:

保证 n\leq 18q\leq 2\times 10^5

Problem C

给定一棵有根树,树上每个点有一个灯泡和一个小精灵。灯泡有亮灭两种状态,初始时都是灭的。在一次操作中,你可以改变某个灯泡的状态。你希望按一定顺序操作这些灯泡,使得:

请求出满足以上条件的最小操作次数。

保证 n\leq 2\times 10^5

题解

Problem A

注意到,对两个区间 X,Y,假设 XY 左侧,那么从 X 出发到达 Y 时,为了使路程最短,我们每次一定会选取当前能走到的区间中最右边的那个。我们可以对每个区间预处理出它向右最优能走到的那个区间,并在两个区间之间连一条有向边,这样会形成一棵有根树的结构;然后做树上倍增就可以在单次 O(\log n) 的时间内回答两点间的最短路了,也就解决了第一个问题。

接下来解决第二个问题。方便起见先暂定全部的区间都是特别的。显见区间 Z 出现在 X,Y 的至少一条最短路上意味着 Z 一定位于 X,Y 中间,且 \mathrm{dis}(X,Z)+\mathrm{dis}(Z,Y)=\mathrm{dis}(X,Y)。令 k=\mathrm{dis}(X,Y),对每个 c=0,...,k,我们希望统计满足 \mathrm{dis}(X,Z)=c,\mathrm{dis}(Z,Y)=k-c 的区间 Z 的数量。不妨设 X 向右走 c-1 步、c 步分别最远能走到的区间编号为 r_{c-1},r_cY 向左走 k-c-1 步、k-c 步分别最远能走到的区间编号为 l_{c-1},l_c,那么我们待求的区间 Z 的编号取值就是 (r_{c-1},r_c][l_c,l_{c-1}) 的交集。注意到:

综合以上两条得到:两个区间的交集恰好就是 [l_c,r_c],故合法区间共 r_c-l_c+1 个。那么我们计算 \sum{(r_c-l_c+1)} 即可求得总答案。注意到这实际上就是查询树上的一段祖先 - 后代链上每个点编号的和,树上倍增也可解决。

回到原题。如果全部区间不一定都是特别的,可以将每个区间的权值改成编号小于等于该区间的所有区间中的特别区间数量。这样就可以在 O(n\log n) 的时间复杂度内解决原题了。

Problem B

倒着考虑这个过程:我们从 e 开始,在 s 秒内不断游走,每次走到一个点该点就会被控制,之后我们可以不断获取该点产出的金币;需要最大化获得的总金币数。

对一个最后被控制的点,我们定义其 损失量 为在我们走到该点之前该点产出的金币总量。假设我们最后控制的点集为 S,设 S 中产出金币的总速度为 v,损失量的总和为 k,此时消耗的时间为 t。那么需要满足 t\leq s,且此时我们得到的金币总量即为 vs-k。对固定的 Sv 也是固定的;我们希望最小化 k 的值。考虑通过状压 DP 计算出对每个 Sk 能取到的最小可能值;这样,我们每次在所有的 S 中,取 vs-k 最大的即可。

在设计状态时,值得考虑的是:需不需要把 t 算进状态里?我们发现,如果 t 需要进入状态,那么状态总数可能是无法承受的;但要是不算,又有 t\leq s 的限制。幸运的是,如果 t > s,那么说明我们还有某个点是没有访问到的,并且我们提前计算了这个点产生的损失量;如果我们把这个点去掉(也就是缩小 S),一定可以找到一组更优解。这说明 t > s 的时候我们就算计算到了,它也不会影响答案。

我们的 DP 便出来了:对每个点集 S 和顶点 u,v\in S,记 f(u,v,S) 为从 u 开始游走,在 v 结束游走,经过了 S 中全部节点,能达到的损失量的最小值。如果考虑每次在 v 端添加一个节点,转移会很困难,因为贡献涉及到总共消耗的时间;我们考虑在 u 端添加一个节点,这样贡献就是这条边的边权乘上点集内所有点的产出速度和。也就是:

f(u',v,S\cup\{u'\})\gets f(u,v,S)+\mathrm{dis}(u,u')\times \sum_{x\in S}m_x

其中 \mathrm{dis}(u,u') 表示图上 u,u' 两点间最短路。以及,可以注意到上面 DP 中第二维事实上是无用的,可以去掉。

最后考虑如何快速查询答案。相当于给定平面上若干直线,多次询问某竖线和这些直线交点的最高位置。可以用李超线段树 / 半平面交等技巧解决。令 K=2^n,时间复杂度 O((q+K)\log K)

Problem C

考虑树形 DP。考虑根节点被满足的过程,我们需要把一棵全白的树完全涂黑,最后又要完全涂白。考虑这个过程中能额外满足哪些点,显见只能是涂黑过程中第一棵被涂黑的子树中的点,以及被涂白过程中最后一棵被涂白的子树中的点;我们不妨认为这两棵子树对应的根节点(也就是当前根的两个儿子节点)各获得了一次 机会。注意到这两个儿子节点可能是相同的,因而可能会有一棵子树同时获得两次机会。

f(u,t)(t\in \{0,1,2\}) 表示当以 u 为根的子树获得 t 次机会的时候,满足整个子树内条件的最小代价。枚举染黑全部子树的这个过程会顺带满足哪些点,可以得到以下转移:

f(u,0)\gets f(v_1,1)+f(v_2,1)+\mathrm{sz}(v_1)+\mathrm{sz}(v_2)\sum_{v\in \mathrm{son}(u),v\neq v_1,v\neq v_2}(2\times \mathrm{sz}(v)+f(v,0))+2 f(u,0)\gets f(v_1,2)+\sum_{v\in \mathrm{son}(u),v\neq v_1}(2\times \mathrm{sz}(v)+f(v,0))+2 f(u,1)\gets f(v_1,1)+\sum_{v\in \mathrm{son}(u),v\neq v_1}(2\times \mathrm{sz}(v)+f(v,0))+2

时间复杂度 O(n)