专题题解 - JOI 2021 Final

打 * 号表示没有写的题,基本上是暂时没来得及写。


A. とてもたのしい家庭菜園 4

难度:$\bigstar$

题目大意:

给定长度为 $n$ 的序列 $a_1,\ldots,a_n$,每次操作可以给一个区间加上 $1$,求最少要多少次操作可以使得 $a$ 变为严格单峰的。

$2\leq n\leq 2\times 10^5$

题目解法:

严格单峰等价于差分序列 $c_1,\ldots,c_{n-1}$前一部分为正,后一部分为负。

一次操作可以将差分序列中一个靠前的位置加 $1$,靠后的位置减 $1$,因此我们可以枚举峰的位置,将差分序列两边需要加/减的次数取最大值即可,这可以通过统计 $\max(0,1-c_i)$ 的前缀和以及 $\max(0,c_i+1)$ 的后缀和求出。

时间复杂度为 $O(n)$。


B. 雪玉

难度:$\bigstar$

题目大意:

数轴上有 $n$ 个雪球,初始位置为 $x_1<\ldots<x_n$,接下来依次进行 $q$ 个操作,第 $i$ 个操作为将所有雪球同时向左/向右移动 $w_i$ 距离。

每一个单位长度上有一单位质量的雪,雪球滚过这一单位长度后就会带走其上的雪,求每个雪球在全过程中的质量增加量。

$1\leq n,q\leq 2\times 10^5$

题目解法:

显然每个雪球滚过的雪是一段区间,只要求出其左右端点即可。

执行前 $i$ 个操作后初始位置为 $x$ 的雪球曾经经过的位置设为 $[x-l_i,x+r_i]$,那么我们对于每个 $i$ 找到最大的 $j$ 使得 $x_i+r_j<x_{i+1}-l_j$,这说明前 $j$ 个操作中 $i$ 和 $i+1$ 两个雪球没有到达公共的区域,但第 $j+1$ 次操作时它们经过的区域就有交了,我们可以通过 $j$ 来算出 $i$ 滚过的雪的右端点和 $i+1$ 滚过的雪的左端点。

而这个 $j$ 是可以二分的,时间复杂度为 $O(n\log q+q)$。


C. 集合写真

难度:$\bigstar$

题目大意:

给定 $1,\ldots,n$ 的排列 $p_1,\ldots,p_n$,每次操作可以交换相邻两个元素,问最少要多少次操作可以使得 $p_i<p_{i+1}+2$。

$3\leq n\leq 5000$

题目解法:

显然操作次数就是前后相对的逆序对数,同时不难发现最后的排列是首先把 $1,\ldots,n$ 划分成若干连续段,再把每一段反序。

设 $dp(i)$ 表示将 $1,\ldots,i$ 分段,只考虑这些段中数的逆序对数量最小值,那么考虑加入 $[l,r]$ 这一段造成的贡献,也就是:

  • 原排列中某个 $x\in [l,r]$ 在 $y\in [1,l-1]$ 之前:暴力求出 $f(i,j)$ 表示原排列排在 $i$ 后面的 $<j$ 的数有多少个即可;
  • 原排列中某个 $x\in [l,r]$ 在 $y\in [l,r], y>x$ 之前:求出原排列所有顺序对再二维前缀和。

时间复杂度为 $O(n^2)$。


D. ロボット

难度:$\bigstar\bigstar$

题目大意:

给定 $n$ 个点 $m$ 条边,边有权值和颜色的无向图,改变一条边需要一定的代价,求最少要付出多少代价,使得存在一条 $1\to n$ 的路径 $1=x_1\to \ldots\to x_m=n$ 使得对于任意 $x_i$ 都不存在一条不同于 $x_i\to x_{i+1}$ 的邻边与 $x_i\to x_{i+1}$ 同色。

$2\leq n\leq 10^5, 1\leq m\leq 2\times 10^5$

题目解法:

设某个点的所有邻边有 $k$ 种不同的颜色 $t_1,\ldots,t_k$,将该点拆成 $k+1$ 个点 $p_1,\ldots,p_{k+1}$,其中 $p_i (i\leq k)$ 表示要选择一条颜色为 $t_i$ 的出边且不改变其颜色,而 $p_{k+1}$ 表示选择的出边改变了颜色,根据上述定义建图求最短路即可。

注意对于 $p_1,\ldots,p_k$ 需要建立一个汇聚点 $P_i$ 以压缩边数。

时间复杂度为 $O(m\log n+n)$。


*E. ダンジョン 3

难度:$\bigstar\bigstar\bigstar$

题目大意:

地牢有 $n+1$ 层,第 $i$ 层到第 $i+1$ 层需要付出 $a_i$ 能量,第 $i$ 层中可以花费 $b_i$ 金币恢复 $1$ 能量(可以同一层多次恢复),有 $m$ 个询问,每个询问给定 $s,t,u$,求能力上限为 $u$ 的情况下从第 $s$ 层走到第 $t$ 层所需要的最小金币数量(或报告无解)。

$1\leq n,m\leq 2\times 10^5$

题目解法:

首先考虑 $t=n+1$ 的情况,这是比较简单的,对于某个 $s\leq i\leq t$,设 $j$ 是满足 $s\leq j<i$ 且 $b_j\leq b_i$ 的最大数,$k$ 是满足 $i<k\leq t$ 且 $b_k<b_i$ 的最小数,再设 $D_1,D_2$ 分别为 $j\to i, i\to k$ 需要付出的能量之和,那么:

  • 假如要从 $i$ 恢复能量,那么在 $j$ 处时能量必须是满的(否则可以在 $j$ 处恢复),所以 $i$ 处恢复能量不会超过 $D_1$;
  • 经过 $i$ 后到达 $k$ 时能量一定为零(否则可以少恢复一点),所以 $i$ 处恢复能量不会超过 $D_2$,也不会超过 $D_1+D_2-u$;
  • 不能超过能量上限,所以 $i$ 处恢复能量不会超过 $u$。

综上,$i$ 处恢复能量的值是关于 $u$ 的线性分段函数。

于是我们考虑倒序扫描 $s$,计算每个 $u$ 的答案,在维护单调栈的基础上,根据上面的分析可以通过区间加等差数列的线段树进行维护。

再考虑 $t<n+1$ 的情况,感觉这才是真正的难点:我们可以找到距离 $t$ 不超过 $u$ 的 $b$ 最小的位置 $x$,则到达 $t$ 时最后一部分能量一定是在 $x$ 这里恢复的,那么 $s\to t$ 的答案就相当于 $s\to n+1$ 减去 $x\to n+1$ 再加上 $x\to t$ 这部分只用 $x$ 的代价。

时间复杂度为 $O((n+m)\log n)$。