20241015 最短路与生成树
@. The army of Thutmose III
题号是 @,原因是过了之后才发现测不了被删了。
注意到问题形如最大值最小,直接上二分答案。考虑如何 check。设当前 check 的答案为 。
容易获得一个猜想,点一定放在区间端点上。那么将区间端点离散化。记 表示第 个位置放了 个点。
对 作前缀和获得 ,那么分析 具有什么性质。容易发现:
容易发现这些性质符合差分约束的形式,直接 spfa 判断,最后对求出的 作一遍差分就能知道在哪些位置放点。
A. 矩阵游戏
容易发现,只要确定了某一行和某一列就能推出整个矩阵。不妨设第 行和第 列为 ,推出一个初始的 。
但是题目要求 ,那么直接这么构造可能会超出这个范围,那么考虑对 进行一些什么样的操作可以使得 不变。可以看出,对于某一行,我们让奇数位的数字同时加上一个 ,偶数位的数字同时减去 ,这样得到的 矩阵就与原来相同,列同理。那么我们设对第 行进行了 的操作,第 列进行了 的操作,操作后的矩阵就是:
这个形式看上去很接近差分约束,但还需要转化。将奇数行的 取相反数,偶数列的 取相反数,得到:
这个形式就很漂亮了,可以使用差分约束。因为 ,所以 。根据这个不等式直接差分约束即可求出合法的 和 。
I. Dynamic Shortest Path
注意到时限有 秒,而 只有 ,增加边权时即使暴力加也只有 的运算量,所以我们可以考虑暴力一点的想法。有一个显然的做法:每次加完边权后直接跑一遍 dijkstra 求出新的最短路,这样是 的。
这样做常数大一点就过不去了,那么考虑这题有什么特殊的性质。可以发现,如果我们能做到在更新边权后在 时间内更新最短路,复杂度就变成 ,可以通过。注意到这题每次增加边权时都只增加 ,那么每次从 到某个点的最短路变化量一定不会超过 (即变化边权的边的数量)。于是考虑求解最短路的增量。
使用 Johnson 算法的思想,将每条边重新赋权为 ,其中 为原本的最短路。
这样,一条路径上所有边的权值和就为 。当起点 时,,那么路径的权值就为 ,也就是新的最短路减去原本的最短路,即最短路的增量。
因为增量的值域不大,所以我们可以用若干个值域上的队列来实现优先队列的功能。具体地说,对每个最短路的值开一个队列,队列中存放最短路增量为这个值的点。枚举小值域向大值域转移即可求出增量并更新最短路,单次时间复杂度 。这题有些卡常,慎用 long long,开 O2、Ofast 即可通过。
K. Kuroni and Antihype
将每个人看作一个点,那么最后就是求一个最大的生成森林。考虑转化成生成树。建立一个权值为 的 号节点,第一种操作就相当于把点与这个点连边。以 为根,现在每条边的权值为深度较浅的点的点权,考虑将最终的答案先加上所有点的点权和,最后在减去点权和,那么由于除了 以外的所有节点均有且仅有一条父边,我们可以考虑将这个点的权值加到这条边上,那么每条边的权值就变成它连接的两个节点的权值和。
经过一系列转化,问题变成:两点之间有边当且仅当 ,边权为 ,求最大生成树。
执行类似 kruskal 算法的过程。注意到边权的值域只有 ,那么考虑从大到小枚举边权并考虑连边。注意到当 时,,说明在二进制下 都是边权的子集。根据这个性质,直接枚举边权在二进制下的子集。如果存在这样的点,就应该连边了。对于一种权值的所有点,记录它们是否已被连接到同一连通块中即可。具体可以画图加深理解。时间复杂度 。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】