JOISC 2021 简要题解

「JOISC 2021 Day1」饮食区

  • 维护 n 个队列,支持 m 次操作:
    • [l,r] 号队列的尾端均加入 k 个颜色 c 的球。
    • [l,r] 号队列的前 k 个球 pop,如果不足 k 个则清空队列。
    • 输出第 a 号队列第 b 个球的颜色,如果不足 b 个球输出 0
  • n,m2.5×105,k109,b1015

一开始 naive 地以为直接删除了就给 b 记录一个偏移量 k,然后整体二分即可。

唯一不足的地方在于,如果队列清空,就不能加上对应删除的 k,而是只加上 size

正着求这个 Δ 不好做,考虑维护每个队列当前的球数 x,以及总共进入过队列的球数 y,那么 Δ=yx

维护当前队列球数,相当于每次 i[l,r],ximax(xi+v,0)

这玩意挺经典的,可以直接用矩阵拟合,也不用真的维护矩阵,而是手玩两下得到合并式。

(a,b) 表示 ximax(xi+a,b)(c,d) 同理,那么 (a,b)(c,d)=(a+c,max(b+c,d))

「JOISC 2021 Day2」道路建设

  • 输出 n 个点中两两前 k 小哈密顿距离的值。
  • n,k2.5×105

肯定是一手二分答案。

然后我的思考是硬上三维偏序,实际上判定的时候,相当于 n 个矩形数点,离线下来即可。

更巧妙的可以转切比雪夫,用一个 set 维护 y 坐标暴力跳就行,找到一个花费 O(logn),找到 >k 个直接 return false 即可。

「JOISC 2021 Day3」保镖

  • n 个 vip 在直线上行走,表现为从 ti 时刻开始从 ai 走到 bi,每个单位时间走一个单位长度。
  • 你作为保镖也在行走,如果你某个时刻与某个 vip 位置重合,那么你可以开始保护他,每保护 vip i 一个单位时间就会获得 ci 的收益。
  • q 次询问,每次给出你可能的开始行走的位置和时间,求你最终能获得的最大收益。
  • 即使你某个时刻与多个保镖重合,你也只能保护一个。同时,你可以不完整的保护一个 vip,甚至可以不保护他整数单位时间。
  • 但是数据保证 ci 为偶数,可以证明这种条件下答案也一定为整数。
  • n2800,q3×106,t,a,b,c109

行走是一维的,但是有时间轴,所以实际上是二维问题,一定记得将问题转化到坐标系上。

先不急,先考虑一个性质:保镖不会停留。

因为停留无非是为了等待一个 vip,但是一直往他的方向走,并且在相遇的那条边先走 12 再折返是不劣的,所以不用停留。

将问题表达到坐标轴上,那么每个 vip 为线段 (ti,ai)(ti+|aibi|,bi),一定是平行于 y=±x 的。

不如旋转 45,进行 (x,y)(x+y,xy) 的变换(虽然这实际上是:逆时针旋转 45 并按 y=x 对称并伸长 2 倍,但无关紧要)。

发现转化为二维问题也乘了个 2,所以直接令 cici2 就好了。

因为 vip 数很少,所以直接离散化能得到一个 2n×2n 的网格图,边有边权和长度,可以直接把图建出来。

问题转化为:给定网格图,你从某个位置出发,只能往右或往上走,每在一条边上走一个单位长度就能获得对应边权的收益,最大化总收益。

格点可以直接简单 DP,但是你可能是从非格点出发的。

显然最优决策一定是:先沿着一个方向走到某条格线,再沿另一个方向走到最近的格点,之后直接利用格点的 DP 值作为答案。

不同初始方向可以分开求解,以先往右为例。

此时可以每行分开处理,倒序维护,相当于每次插入一次函数 y=kix+bi,每次询问给定 xmaxy

可以直接用李超树,因为是插入直线,所以复杂度 O((n2+q)logn)

实际上能做的更好,转化一下能变成 bi=(ki)x+y,最大化截距 y 所以维护上凸壳。

同时观察到 bi 的单调不降性,所以如果 ki 不是递增的,那么一定不优,所以可以理解为 ki 是递减的,即插入点的横坐标递减。

直接维护单调栈,每次二分即可,复杂度 O(n2+qlogn)

「JOISC 2021 Day3」聚会 2

  • 对于一个树上有 k 个点的点集,定义 S 为它们的决策集合,s 包含所有到这 k 个点距离和最小的点。
  • 现在 k 个点可以钦定,求 k[1,n],|S|max
  • n2×105

不难发现 k 为奇数的时候,一定有 |S|max=1,且这个点是 k 个点中的一个。

更进一步的,发现 k 为偶数时,答案就是最长的路径长度,使得路径两端点的子树大小均 k/2

统计路径长度使用点分治,每次开桶维护每个子树,桶的大小为 sizv,所以可以直接合并,每个桶时刻要取后缀 max

「JOISC 2021 Day4」活动参观 2

  • 给定 n 个活动,每个活动需要占用一段连续的时间 [li,ri]
  • 求字典序最小的长度为 k 的序列,使得序列中的活动时间无交。
  • n105,li<ri109

一开始是想着线段树优化建图的,但是应当是假了。

考虑对着字典序贪心,如果加入这一段后,最终还能得到 k 段就直接加入。

只需要维护函数 calc(l, r) 表示对于子区间 [l,r] 最多能选几个线段,那么就可以直接贪心。

然后这种选不交区间的模型也是经典的倍增优化贪心了。

「JOISC 2021 Day4」最差记者 4

  • 每个人三个参数 (a,h,c),分别表示 hihai,以及修改 hi 需要 ci 的代价。
  • 需要满足所有不等关系,求最小修改代价。
  • n2×105,hi,ci109

遇到很多次这种线段树合并优化 树上带前后缀 max/min 之类的转移式了。

一定记住重要思想是,因为是前后缀,只要能取到答案就行,具体点值可以含糊。

显然连出来一棵内向基环树森林,把环拆了,先对子树求解。

一般都先想暴力一点,设 f(u,x) 表示点 u 的值取 x 的最小代价,则:

f(u,x)=[xhu]cy+vsubtree(u)minyxf(v,y)

树上的点值,会取到的只有出现过的点值,所以是 O(n2) 的。

对于环上的点,它们的值肯定全都相等,要么等于环上某个点的值,要么 =1,枚举统计即可,这一部分是 O(n) 的。

这种转移方程一看就是能线段树合并优化的,但是最前面一项 [xhu]cy 意味着每次都要进行前后缀加。

线段树合并每次只能修改已有节点或插入有限个节点,这样强行打区间加 tag 肯定是会出问题的。

实际上,简单转化一下,f(u,x) 表示能保留的最大的代价和,那么:

f(u,x)=[x=hu]cy+vsubtree(u)maxyxf(v,y)

维护子树 max,然后右子树对左子树有贡献,同时如果一个节点为空,那就对另一个直接区间加。

显然为了保证复杂度不能继续合并下去,而区间加看似没有对每个位置加上自己的后缀 max,因为左右均为空时,区间加没贡献上去。

实际无关痛痒,因为每次还是能取到后缀 max。也因此,查询 f(u,x) 的时候要查询整个 [x,V] 后缀。

补集转化的思想还是挺重要的!

posted @   LPF'sBlog  阅读(452)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示