Canadian Computing Olympiad 2020
链接
A | B | C | D | E | F |
---|---|---|---|---|---|
$\color{gray}{\texttt{-}}$ | $\color{green}{\texttt{+}}$ | $\color{gray}{\texttt{-}}$ | $\color{green}{\texttt{+6}}$ | $\color{green}{\texttt{+}}$ | $\color{red}{\texttt{+3}}$ |
A. A Game with Grundy
直接把每个朋友的视野在 $y=Y$ 上截得的整点区间求出,然后离散化之后扫一遍即可。
B. Exercise Deadlines
题目可以转化成:构造一个排列,满足 $p_i\leq d_i$,要求 $p_i$ 逆序对个数尽可能少。
直接贪心,从后往前贪心取没有被取的数且 $\leq d_i$ 中最大的。容易证明取更小的会使逆序对个数增加,并且更不容易合法。
最后再求一遍逆序对个数,复杂度 $O(n\log n)$。
代码
1 |
|
C. Mountains and Valleys
如果没有非树边,答案是两倍边数减去直径边数。
结论:至多只会选一条非树边。这个比较好证,因为如果选了两条,答案至少为 $\frac{5n}{3}$,然而此时直径长度有 $\frac{n}{3}$,所以不如直接跑原树
加上树边之后的策略是:断掉对应路径上的一条树边,最大化直径。
分类讨论直径与环的关系即可。
D. Travelling Salesperson
挺妙的题。结论是:以任意点出发的最短路径合法长度都是 $n$。
考虑用增量法构造。假设当前有一条合法路径,要插入点 $u$,如果当前路径全部同色,那么直接将 $u$ 插入末尾一定合法。否则假设路径异色的分界点为 $v$,其前驱为 $v_L$ 后继为 $v_R$,如果 $(u,v_L)$ 与 $(u,v)$ 同色,那么直接将 $u$ 插入 $v_L$ 与 $v$ 直接,如果 $(u,v)$ 与 $(u,v_R)$ 同色那么插入 $v$ 与 $v_R$ 之间。如果都不满足那么 $(u,v_L),(u,v_R)$ 与 $(v_L,v),(v_R,v)$ 中的至少一条同色, 插入另一条边即可。
构造就是对结论的证明。
代码
1 |
|
E. Interval Collection
首先容易证明,最优集合中一定只有至多两个区间。
分类讨论:
- 如果不存在无交区间,那么最小的交一定是 $r$ 最小的区间与 $l$ 最大的区间。
当然 $r$ 相同的区间可能有很多,根据题目要求选最大的即可。$l$ 同理。这部分可以用multiset
解决。 - 如果存在区间无交,不妨枚举分界点 $p$,相当于在 $p$ 左边找一个左端点最大的,右边找一个左端点最小的。
如果每次取当前需要处理的区间 $[l,r]$ 的中点 $\text{mid}$,那么本质上是问右端点在 $[l,mid]$ 的区间中左端点最小值,$[ mid+1,r]$ 同理。可以发现这就是线段树的过程,直接用线段树维护即可。
复杂度 $O(n\log n)$。
代码
1 |
|
F. Shopping Plans
牛逼题。
首先当然组内排序。考虑先处理 $x_j=y_j=1$ 的部分,也就是说每个组只会选择一个数字。
一种很显然的做法是:维护每个序列指针和一个位置 $p$ 表示当前已经处理到 $p$ 对应组。每次从队列中取出最小值,将 $p$ 对应组往后移一位,或者选择一个 $p’>p$ 后移一维,容易证明是不重不漏的。复杂度 $O(n^2\log n)$。
可以发现这样非常浪费,因为每次都要枚举 $p’$,决策数量 $O(n)$。思考能不能一次只移动 $p’\leftarrow p+1$。
但是直接做是不行的,因为如果我们只让 $p’=p+1$,那么新状态实际上和原先相同。如果钦定 $p’$ 对应组移动一步,然而每一组不一定强制移动。
考虑增加一个“反悔”机制,即:如果 $p’=p+1$ 然而 $p$ 对应组只移动了恰好一步,我们可以认为这一步是为了转移“被迫的”,在令 $p’$ 移动一步的同时撤销 $p$ 的移动。
不过这样要求对于 $p’>p$,$p’$ 移动第一步一定要比 $p$ 移动第一步要优,因为我们无法在 $p$ 移动第一步之前将 $p’$ 放入堆。所以开始时将组按 $a_2-a_1$ 从小到大排序即可。复杂度 $O(k\log k)$。
考虑 $m=1$ 的部分,即需要对组内处理。首先枚举所有可行长度 $L\in[x_i,y_i]$,将前 $L$ 个字符加入初始队列。
队列中维护 $l,r,p$,表示当前在修改 $p$,其中 $p$ 从 $l$ 位置开始,不能超过 $r$。每次操作可以:将 $p$ 后移一位,或者将 $l$ 设置为 $l-1$,同时 r=p , p=l-1
。这样每次只有两种决策,复杂度 $O(k\log k)$。
最后对于正解,将每个组当成一个黑箱子,可以发现黑箱子中的操作只有输出下一个的解,这恰好就是 $m=1$ 时求的东西,直接两层 $k$ 短路即可。复杂度 $O(k\log k)$。
代码
1 |
|