专题题解 - JOI 2020 Final

打完发现是最简单的 JOI Final。


A. 長いだけのネクタイ

难度:$\bigstar$

题目大意:

给定长度为 $n+1$ 的序列 $a_1,\ldots,a_{n+1}$ 和长度为 $n$ 的序列 $b_1,\ldots,b_n$,定义 $a_i$ 和 $b_j$ 匹配的代价为 $\max(0,a_i-b_j)$,对于每个 $a_i$ 求删除它后 $a$ 与 $b$ 完美匹配的最大代价的最小值。

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

题目解法:

两个序列的最大代价最小的匹配一定是排序后按照顺序匹配,求出 $\max(0,a_i-b_i)$ 的前缀和以及 $\max(0,a_{i+1}-b_i)$ 的后缀和即可。

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


B. JJOOII 2

难度:$\bigstar$

题目大意:

给定长度为 $n$ 的由 $\texttt{J,O,I}$ 组成的字符串 $S$,你可以取其一个子串,然后删去子串中一些字符,使得得到的串为 $k$ 个 $\texttt{J}$,$k$ 个 $\texttt{O}$,$k$ 个 $\texttt{I}$ 依次拼接,求出删去字符的最小值,或报告无解。

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

题目解法:

利用双指针求出每个位置后面第 $k$ 个 $\texttt{J,O,I}$ 分别在哪里,然后枚举子串的左端点,可以直接算出子串的最小右端点。

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


C. スタンプラリー 3

难度:$\bigstar$

题目大意:

有长度为 $L$ 的环,环上有 $n$ 个邮票,第 $i$ 个邮票在起始位置顺时针走 $x_i$ 的位置,如果要收集则必须在 $t_i$ 时刻前到达 $x_i$。

你的速度为 $1$,从起始位置出发,问最多能收集到多少邮票。

$1\leq n\leq 200, 2\leq L\leq 10^9$

题目解法:

区间 DP,设 $f(l,r,k,o)$ 表示将 $x_i$ 排序后,当前走过的区域覆盖了 $x_1,\ldots,x_l$ 以及 $x_r,\ldots,x_n$ 这些点,并且收集到了 $k$ 个邮票,$o=0$ 表示现在在 $x_l$,$o=1$ 表示现在在 $x_r$,其值为当前的最小时间。

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


D. オリンピックバス

难度:$\bigstar\bigstar$

题目大意:

给定 $n$ 个点 $m$ 条边的无向图,每条边有长度 $c_i$ 和翻转代价 $d_i$,你可以选择至多一条边进行翻转,使得从 $1$ 走到 $n$ 再走回 $1$ 的最短路加上翻转的边的翻转代价最小。

$2\leq n\leq 200, 1\leq m\leq 50000$

题目解法:

求出 $1,n$ 在原图和反图的最短路,并各求最短路树,翻转一条边时:

  • 如果这条边不在四个最短路树上的任何一个,那么可以 $O(1)$ 计算翻转后 $1\to n$ 和 $n\to 1$ 最短路(因为 $1,n$ 出发和到达的最短路都不会变大);
  • 否则,由于在最短路树上的边只有 $O(n)$ 条,每次暴力重新 dijkstra。

时间复杂度为 $O(n^3+nm)$。


E. 火事

难度:$\bigstar\bigstar$

题目大意:

给定长度为 $n$ 的序列 $S_1,\ldots,S_n$,初始时间为 $0$,每过一秒,所有 $S_i$ 会变成上一秒 $S_i$ 与 $S_{i-1}$ 的最大值($S_1$ 不变)。

现在有 $q$ 个询问,每次询问第 $t$ 秒后 $S_l+\ldots+S_r$ 的值。

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

题目解法:

不妨认为 $S_i$ 是排列(否则可以将相同的元素强制给定一个序),一个简单的结论是:任意时刻某个数出现的位置是一段连续区间(可能为空),并且不同的数出现的顺序等同于在初始序列中的顺序,这一点不难归纳证明。

同时,$t$ 时刻处在 $r$ 的数就是 $[r-t,r]$ 中的最大值,可以直接求出,不妨设为 $S_p$。

所以假设 $t$ 时刻 $S_i$ 出现的区间为 $[a_i,b_i]$,那么:

所以我们可以按时间扫描,对于所有 $i$ 维护 $a_i$ 和 $b_i$ 的变化,支持区间查询 $\sum (b_i-a_i+1)\times S_i$ 即可。

分析发现 $a_i$ 和 $b_i$ 只与 $i$ 之前第一个比 $S_i$ 大的数 $S_{L_i}$ 和 $i$ 之后第一个比 $S_i$ 大的数 $S_{R_i}$ 有关,可以表示成常数段分段线性函数,用线段树分别维护斜率之和以及截距之和即可。

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