8.9 JOI 专场

发布时间 2023-08-09 22:10:33作者: _maze

上午下午模拟赛。

期望得分 100 + 12 + 30,实际得分 100 + 12 + 60

第一题用时过长导致没有时间看第二题和第三题。

二分图太弱了!

疑案追凶

我们将相邻的,互不相交的身高区间放到一个询问里,这样肯定是最优的。

因此,我们要做的是对于每个区间,统计出他最远能到达哪里,使经过的地方互不相交。之后就可以用倍增快速计算步数。

由于最远到达的地方单调不减,考虑离散化后线段树加双指针维护区间,每一次将右指针代表的区间加 \(1\),当前区间与已有区间不交的条件为当前区间和为 \(0\)

时间复杂度为 \(O(n\log n)\)

我知道阁下的解题能力很强,但是如果嫌疑人不能随便长高,阁下该如何处理

猫爬架

玩玩链的部分分,发现最优策略是堵住一边,另一边不放。很好证。堵得不全,要么答案变小,不如不堵,要么和堵住没有区别。另一边堵了,答案必定变小。因为此时活动区间必定变小。

于是扩展到树上:堵住除一边外的所有边,不停重复这个过程。每次最终会走到这条边对应子树区间最大值。

考虑 dp。设 \(f_{i}\) 表示从 \(i\) 走的答案,发现两个点能转移的条件是中间没有比他们大的 \(h\),那么此时 \(f_i = \max(f_j + dis(i,j))\)

发现有可能会走到祖先,于是我们改变 dp 顺序,设 \(f_i\) 为从 \(h_u = i\)\(u\) 出发得到的答案,从 \(1\) 开始转移到 \(n\)。每次转移后用并查集合并点,便于将来的转移。

巴士走读

\(m\) 辆巴士。每辆巴士在 \(X_i\)\(A_i\) 出发,并在 \(Y_i\) 到达 \(B_i\)。有 \(Q\) 次询问。每次询问给出最晚到达 \(n\) 的时间,问最晚可以在什么时间在 \(1\) 上车。

看起来时间是连续的,实际上却是分段的。

上车时间一定等于一辆车的发车时间。因此考虑对询问二分。

考虑预处理。按到达时间倒序排序 \(1\) 出发的车,一辆一辆加入。对于加入后能够到达的 \(u\),也像这样一辆一辆加入。对于所有的 \(u\) 来说,加入的车是几段不交的区间。所以加入复杂度为 \(O(n)\)

有趣的家庭菜园

一个长为 \(n\) 的序列 \(h\),支持邻项交换。先想要对于每个 \(i\),都有一边的所有 \(h_j\) 不大于 \(i\),问邻项交换的最小次数。

贡献题,关键在于每个点的贡献独立计算

转换一下,题目想让我们把序列变成一个山峰状序列。

证明:对于最小的数,必定会放在 \(1\)\(n\)。放完以后剩下的序列是原序列的子问题,得证。

考虑一个点要怎么样才能符合要求。在左右两边任取一边,交换完所有比他大的值之后就符合要求了。因此答案为:

\[\sum_{i=1}^{n}\min(\sum_{j=1}^{i-1}[h_j>h_i],\sum_{j=i+1}^{n}[h_j>h_i]) \]

用树状数组维护即可。

拉面比较

交互题,有一 $n \le 400$ 长度未知序列 \(h\),保证 \(h\) 中数两两不同,支持操作 f(x,y),返回 \(h_x\)\(h_y\) 的大小关系。在 \(600\) 次询问内得出序列最大值位置与最小值位置。

经典减少比较次数的策略:分类。

考虑简单策略:遍历时只与已遍历到的最大值,最小值进行比较。

这还是不够快。我们首先两两分组比较,大的只参与最大值比较,小的只参与最小值比较。注意这样可能会剩一个数,要把它加到两种比较当中去。

水壶

\(n \times m\) 的方格,上面有城市,障碍,空地三种。空地走一格消耗一升水,走到城市可以让你的水壶补满水,\(Q\) 组询问,询问最小需要多大的水壶可以从 \(S\) 走到 \(T\)

口胡的。

如果把城市看作点,那么这个就是最小生成树的路径上的最大值。

考虑如何建边。从每个城市多源 bfs,如果城市 \(u\) 扩展时碰到了城市 \(v\) 扩展到的点就连边,距离记录 \(v\) 扩展到的时间可以求了。

由于此时每一个空地最多会从 \(4\) 个方向被扩展到,所以总时间复杂度为 \(O(nm)\)