JOI Final 题解

需要写一下的题:

  • [x] 「JOI 2017 Final」绳
  • [x] 「JOI 2016 Final」断层
  • [x] 「JOI 2016 Final」领地
  • [ ] 「JOI 2013 Final」 冒泡排序
  • [ ] 「JOI 2015 Final」城墙
  • [ ] 「JOI 2019 Final」独特的城市
  • [ ] 「JOI 2020 Final」奥运公交
  • [ ] 「JOI 2020 Final」火灾

为什么 JOI Final 的题前三个都是水,最后两个超勇的。

Update:一道后两个题都做不出来 「大哭」

JOI 2013 Final

「JOI 2013 Final」JOIOI 塔

小米同步赛 T1 和这题类似,当时没见过都自闭了 😭

考虑二分答案,那么尽可能在最后面选出来 mid 个 OI,然后前面拼 I 和 J 即可。

「JOI 2013 Final」 冒泡排序

有趣的思路题。不交换的答案就是逆序对数,我们把点化为二维座标上的点 \((i,h_i)\),交换的两点一定满足 \(i < j,h_i>h_j\),这样逆序对数会减少矩形内点个数 * 2 + 1,我们找到最大的矩形即可。不难发现左上角一定是一个前缀最大值,右上角一定是一个后缀最小值,可以使用决策单调性来做(更普遍),但在这题中有更棒的性质,左上角是向右上走的斜线,右下角也是,考虑每个点的贡献,发现对左上斜线的一个区间可以右下斜线的一个区间选出来两个点形成的矩形有 1 的贡献,可以抽象到另外一个二维平面上,矩形加查询最大值即可。

JOI 2014 Final

「JOI 2014 Final」飞天鼠

以为是神仙建图,结果是神仙贪心。

发现上升和下降的代价再哪里都一样,我们在需要上升和下降的时候再进行操作。

这代表着我们从起点开始跑最短路,(在贪心的前提下)到达一个点的最短路和到达一个点时最高的高度是“统一的”,也就是最短路可以确定高度。考虑到达一个点最高的高度非 0,说明到达这个点之前没有使用上升操作,显然越高最短路也越小。如果高度为 0,直接记录最短路即可。

「JOI 2014 Final」裁剪线

参考题解:https://blog.csdn.net/qq_42101694/article/details/104775768

考虑使用从下至上扫描线解决(先扫竖线入点,然后横线,然后竖线出点),扫到一个竖线入点,不会改变连通情况,将经过的地方分裂为两个块。扫到一个横边,将完全覆盖掉的区域新建连通块,表示和原先完全分裂。扫到一个竖线出点,两个区域连为一个连通块。不可以暴力新建连通块的,我们采用在平衡树上打 Tag 的方式。碰到竖线直接下传 Tag,碰到二操作将答案加上区间内“被打上标记而没有新建节点”块的个数。

细节较多,但如果精细的实现起来并不复杂,是一道不错的题目。

JOI 2015 Final

这场略微简单一点啊。

「JOI 2015 Final」舞会

一开始看错题了 😅

树形结构永远的神,考虑二分答案,对于给定的序列来说,我们将其看成一个 01 串,发现可以建出一个决策树出来,设 \(dp[x]\) 表示节点为 1 则至少要放置多少个 1,合并上去为 1 的条件就是有至少两个都为 1。

「JOI 2015 Final」城墙

巧妙的二维数点问题,这里数正方形我们采用数左上角和右下角 pair 的个数。

枚举对角线,那么对于一个左上角,我们求出它向右向下最远延申到哪里,两者取 min 设为 \(y_i\),其横座标设为 \(x_i\),右下角横座标为 $ y_j$,最远向左延申到的横座标设为 \(x_j\) ,两个点可以组成一个 pair 当且仅当 \(x_j \le x_i,y_j \le y_i\),不难发现是一个二维数点问题,扫描线解决即可。

JOI 2016 Final

「JOI 2016 Final」领地

题解

设一轮过后 x 变化 \(p\),y 变化 \(q\),特判 \(dx = 0,dy =0\) 的情况。不妨设 \(dx > 0\),否则 \(\mathbb{swap}(x, y)\)

对于被走过的一个点 \((x,y)\) 来说,可以表示为 \((x'+rp,y'+rq)\),其中 \((x'< p)\)。为什么要这样表示?因为我们可以发现,r 的范围是一些区间,区间的总和是 \(\Theta(n)\) 级别的!

所以可以用一个二元组 \((x,y)\) 和一个区间集合 \([l_1,r_1],[l_2,r_2]\cdots [l_n,r_n]\) 来表示 \((x+tp,y+tq)(t \in [l_i,r_i])\) 的点。

我们考虑如何统计答案,枚举矩形的左下角,考虑 \((x,y),(x+1,y),(x,y+1),(x+1,y+1)\),取它们区间集合的并集即可(如果 \(x = p\) 要把区间集合平移一下),暴力枚举复杂度就是对的,实现可以暴力一些以减少代码量。

一种可能的实现是按左端点归并,维护右端点最远到达多少,每次答案就是 \(\max(\min(newl, \min(r)) - nowl,0)\)

「JOI 2016 Final」断层

由于初始点太多了,我们倒着考虑,这样就可以做到 \(\Theta(n^2)\) 了,思考如何优化这个过程:

  • 对于 \(x - y \le k\) 的点,对 \(x,y\) 都减去 L。
  • 对于 \(x + y \ge k\) 的点,对 \(x\) 加上 L,\(y\) 减去 L。

我们直接用一个二元组 \((A,B)=(x+y,x-y)\) 表示这个点,重新考虑这个过程:

  • 对于 \(B \le k\) 的点,A -= 2L
  • 对于 \(A \ge k\) 的点,B += 2L

发现初始状态是 \((A,B)=(i,i)\) 单调递增,经过我们这两个操作依然单调递增!

所以说就可以二分到对应的位置然后区间加减即可,可以用树状数组优化代码量和常数。

树状数组上二分这种科技原来早就有啊!

JOI 2017 Final

具体来说,对于一个点 x 来说,找到最近的快车点,然后找到最近的中快车点,最后做慢车到达。

所以可以设出暴力 dp,算出每一段放 k 个中快车点得到的最大收益是多少,可以获得 \(48 \%\)

这其实是一个揹包问题,每个段的收益函数是一个单减函数,所以直接用堆维护即可。

「JOI 2017 Final」足球

发现 W,H 没有想象的那么大,看起来大概可以类似最短路 dp 的做法,记录毬在 x, y 処最少要多少代价,同时发现性质一个人最多带毬一次,如果带了两次,那么从第一个位置移动到第二个位置的时候带著毬一定更优,所以我们让最近的人走过来。拆点 dijkstra 即可。

「JOI 2017 Final」绳

发现染色一定是开始的时候就染好,最后直接拧成最多两个颜色。

经过手玩发现如果对于一个 01 序列,分成连续段,如果只有左右端点是奇数(偶数也可),中间部分是偶数那么一定有解。

两端长度大于 1 可以不断自卷变成单个颜色,考虑归纳证明,比如左端是 \(1001\cdots\) 一定可以找到 0 的中点然后对折,成功归纳。

正着也可以推,发现每次都是展开左端点或右端点,那么左右端点一定变成偶数,展开的不完整段有可能变成奇数。

枚举两种颜色然后暴力做可以拿到 \(55 \%\)

枚举第一段是奇数还是偶数,剩下的部分发现全是偶数段,偶数段可以拆成两个一对的,一对中的颜色肯定相同,对于颜色 x,y,它们省下来的代价就是 \(cnt_x+cnt_y-cnt_{(x,y)}\)\(cnt_{(x,y)}\) 是指相邻两个为 \((x,y)\) 的个数。

实现时枚举每种颜色,用桶记录一下即可。

JOI 2018 Final

「JOI 2018 Final」团子制作

对于一个团子,只可能会有另外一个方向的团子和它冲突,经过仔细观察,发现冲突的团子的 G 团子都在一条对角线上,不在一条对角线的团子一定不冲突,通过这个进行 dp 即可。

「JOI 2018 Final」月票购买

建出从 S 到 T 的可行最短路图,一定是从 u 到达图上,然后在从图上的某个点走出,所以跑出 u, v 到别处的最短路,建出 s 到 t 的最短路图(单向边),拓扑排序之类的做即可。

「JOI 2018 Final」毒蛇越狱

一个题三种做法拼起来是我妹想到的!

可以根据 0 容斥,根据 1 容斥,暴力枚举,复杂度分别是 \(\Theta(2^{cnt_0})\)\(\Theta(2^{cnt_1})\)\(\Theta(2^{cnt_?})\),发现 \(\min\{cnt_0,cnt_1,cnt_?\} \le 6\),找最小复杂度的做即可。

JOI 2019 Final

「JOI 2019 Final」有趣的家庭菜园 3

首先无解当且仅当最大颜色个数大于其他颜色个数之和 + 1,另外发现同颜色的不会交换,设大暴力 \(f[x][y][z][pre]\) 表示放了 x 盆 r,y 盆 g,z 盆 y 上一盆是 pre 的最少交换次数,枚举下一个放啥就行了。

「JOI 2019 Final」硬币收藏

如果 n 比较小的话可以二分图带权匹配,如果 y = 1 的话直接按 x 座标排序即可。这启发我们先将棋子花费必须的代价将他们移动到合法范围内 \(x \le n,y \le 2\)

我们发现对于一条竖着的分界线来说,不会同时存在左边的点穿到右边去并且右边的点穿到左边来,也就是每条竖线都是单向传递的,这样我们可以轻松算出每条竖线的贡献,但是横线不可以,因为它的范围太大了。

考虑类似均分纸牌式的贪心,从左扫到右,维护两个变量 A,B,时时刻刻保证这两个变量同号即可。

「JOI 2019 Final」独特的城市

暴力怎么做?对于每个点 dfs,找到其最长链,拿次长链将其覆即可,显然不够优,我们考虑优化这件事。

找出树的直径,每个点出发的最长链的端点一定是直径的两端点,所以以两个端点做两遍 dfs,算出最长链的端点为其的答案。dfs 时先走长链,将短链暴力覆盖上去,然后走短链,发现这样一个性质,对于一条重边链接的父亲儿子 \((x,fa)\),fa 的轻边需要覆盖的长度 \(maxdep_{fa}\),有 \(maxdep_{fa}=maxdep_{x}+1\),所以修改一个位置即可。是一道非常巧妙的题。

本质上说:其他对于每个点都有一个需要覆盖的区间,轻儿子需要删除的区间恰好就是长链的长度,而这个是可以转移过来的。

JOI 2020 Final

「JOI 2020 Final」奥运公交

考虑每条边的贡献,如果这条边在 1 到 n 和 n 到 1 的最短路上,这样的边只有 \(\Theta(n)\) 个,可以直接暴力翻转最短路做掉。

不经过它的 1 -> n 最短路和 n -> 1 最短路都已经求得,经过它的最短路就是强制从 1 到 x,然后从 x 到 n 的最短路,有可能会有冲突,但我们可以记录一下次短路(不同前驱的),这样就可以算出来了。

「JOI 2020 Final」火灾

在会了。

https://www.cnblogs.com/zhoushuyu/p/12082371.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章