JOISC 2021 简要题解
「JOISC 2021 Day1」饮食区
- 维护 个队列,支持 次操作:
- 在 号队列的尾端均加入 个颜色 的球。
- 将 号队列的前 个球 pop,如果不足 个则清空队列。
- 输出第 号队列第 个球的颜色,如果不足 个球输出 。
- 。
一开始 naive 地以为直接删除了就给 记录一个偏移量 ,然后整体二分即可。
唯一不足的地方在于,如果队列清空,就不能加上对应删除的 ,而是只加上 。
正着求这个 不好做,考虑维护每个队列当前的球数 ,以及总共进入过队列的球数 ,那么 。
维护当前队列球数,相当于每次 。
这玩意挺经典的,可以直接用矩阵拟合,也不用真的维护矩阵,而是手玩两下得到合并式。
设 表示 , 同理,那么 。
「JOISC 2021 Day2」道路建设
- 输出 个点中两两前 小哈密顿距离的值。
- 。
肯定是一手二分答案。
然后我的思考是硬上三维偏序,实际上判定的时候,相当于 个矩形数点,离线下来即可。
更巧妙的可以转切比雪夫,用一个 set 维护 坐标暴力跳就行,找到一个花费 ,找到 个直接 return false
即可。
「JOISC 2021 Day3」保镖
- 有 个 vip 在直线上行走,表现为从 时刻开始从 走到 ,每个单位时间走一个单位长度。
- 你作为保镖也在行走,如果你某个时刻与某个 vip 位置重合,那么你可以开始保护他,每保护 vip 一个单位时间就会获得 的收益。
- 次询问,每次给出你可能的开始行走的位置和时间,求你最终能获得的最大收益。
- 即使你某个时刻与多个保镖重合,你也只能保护一个。同时,你可以不完整的保护一个 vip,甚至可以不保护他整数单位时间。
- 但是数据保证 为偶数,可以证明这种条件下答案也一定为整数。
- 。
行走是一维的,但是有时间轴,所以实际上是二维问题,一定记得将问题转化到坐标系上。
先不急,先考虑一个性质:保镖不会停留。
因为停留无非是为了等待一个 vip,但是一直往他的方向走,并且在相遇的那条边先走 再折返是不劣的,所以不用停留。
将问题表达到坐标轴上,那么每个 vip 为线段 ,一定是平行于 的。
不如旋转 ,进行 的变换(虽然这实际上是:逆时针旋转 并按 对称并伸长 倍,但无关紧要)。
发现转化为二维问题也乘了个 ,所以直接令 就好了。
因为 vip 数很少,所以直接离散化能得到一个 的网格图,边有边权和长度,可以直接把图建出来。
问题转化为:给定网格图,你从某个位置出发,只能往右或往上走,每在一条边上走一个单位长度就能获得对应边权的收益,最大化总收益。
格点可以直接简单 DP,但是你可能是从非格点出发的。
显然最优决策一定是:先沿着一个方向走到某条格线,再沿另一个方向走到最近的格点,之后直接利用格点的 DP 值作为答案。
不同初始方向可以分开求解,以先往右为例。
此时可以每行分开处理,倒序维护,相当于每次插入一次函数 ,每次询问给定 求 。
可以直接用李超树,因为是插入直线,所以复杂度 。
实际上能做的更好,转化一下能变成 ,最大化截距 所以维护上凸壳。
同时观察到 的单调不降性,所以如果 不是递增的,那么一定不优,所以可以理解为 是递减的,即插入点的横坐标递减。
直接维护单调栈,每次二分即可,复杂度 。
「JOISC 2021 Day3」聚会 2
- 对于一个树上有 个点的点集,定义 为它们的决策集合, 包含所有到这 个点距离和最小的点。
- 现在 个点可以钦定,求 。
- 。
不难发现 为奇数的时候,一定有 ,且这个点是 个点中的一个。
更进一步的,发现 为偶数时,答案就是最长的路径长度,使得路径两端点的子树大小均 。
统计路径长度使用点分治,每次开桶维护每个子树,桶的大小为 ,所以可以直接合并,每个桶时刻要取后缀 。
「JOISC 2021 Day4」活动参观 2
- 给定 个活动,每个活动需要占用一段连续的时间 。
- 求字典序最小的长度为 的序列,使得序列中的活动时间无交。
- 。
一开始是想着线段树优化建图的,但是应当是假了。
考虑对着字典序贪心,如果加入这一段后,最终还能得到 段就直接加入。
只需要维护函数 calc(l, r)
表示对于子区间 最多能选几个线段,那么就可以直接贪心。
然后这种选不交区间的模型也是经典的倍增优化贪心了。
「JOISC 2021 Day4」最差记者 4
- 每个人三个参数 ,分别表示 ,以及修改 需要 的代价。
- 需要满足所有不等关系,求最小修改代价。
- 。
遇到很多次这种线段树合并优化 树上带前后缀 之类的转移式了。
一定记住重要思想是,因为是前后缀,只要能取到答案就行,具体点值可以含糊。
显然连出来一棵内向基环树森林,把环拆了,先对子树求解。
一般都先想暴力一点,设 表示点 的值取 的最小代价,则:
树上的点值,会取到的只有出现过的点值,所以是 的。
对于环上的点,它们的值肯定全都相等,要么等于环上某个点的值,要么 ,枚举统计即可,这一部分是 的。
这种转移方程一看就是能线段树合并优化的,但是最前面一项 意味着每次都要进行前后缀加。
线段树合并每次只能修改已有节点或插入有限个节点,这样强行打区间加 tag 肯定是会出问题的。
实际上,简单转化一下, 表示能保留的最大的代价和,那么:
维护子树 ,然后右子树对左子树有贡献,同时如果一个节点为空,那就对另一个直接区间加。
显然为了保证复杂度不能继续合并下去,而区间加看似没有对每个位置加上自己的后缀 ,因为左右均为空时,区间加没贡献上去。
实际无关痛痒,因为每次还是能取到后缀 。也因此,查询 的时候要查询整个 后缀。
补集转化的思想还是挺重要的!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】