Codeforces Round #665 (Div.2)
橙名留念!
A. Distance and Axis
Solution
不动 $A$ 点的话,距离差最大就是 $x_A$,所以如果 $k>x_A$,把 $A$ 移动 $k-x_A$ 就好。
如果 $k<x_A$,如果 $k$ 与 $x_A$ 同奇偶,那么一定可以找到这么个 $k$;否则 $A$ 需要挪一格。
Code
1 |
|
B. Ternary Sequence
Solution
考虑 $b$ 序列,它的 $2$ 一定是优先去和 $a$ 的 $0$ 去匹配,多了的拿去和 $a$ 的 $2$ 匹配,再多就只能和 $a$ 的 $1$ 匹配了。稍微分类讨论一下就解决了。
Code
1 |
|
C. Mere Array
Solution
设最小值为 $mn$,那么所有 $mn$ 的倍数都可以以 $mn$ 作为“桥梁”任意交换位置,所以 $mn$ 的倍数们一定可以排成有序的。这之后再检验一下整个序列是否有序即可。
Code
1 |
|
D. Maximum Distributed Tree
Solution
显然是考虑每条边的贡献——一条边的贡献就是它两端连接的子树大小乘积,记为 $w$。于是乎,$\text{ANS}=\sum_{i=1}^{n-1}w_ia_i$,$a_i$ 就是我们为这条边分配的值。首先根据排序不等式易知,要想答案最大,一定是最大的 $w$ 配最大的 $a$,最小的 $w$ 配最小的 $a$。其次贪心很容易证明:如果质因数个数超过了 $n-1$,就把最大的几个质因数乘起来,这样答案最大。问题解决。
Code
1 |
|
E. Divide Square
Solution
有两种情况会使答案加一:有一条贯穿整个矩形的直线,或两条直线在矩形内部产生一个交点。
换句话说,答案等于贯穿矩形的直线数量加上矩形内部交点的数量。
前者很好求,对于后者,把所有水平直线按左端点排序,把所有竖直直线按横坐标排序,枚举竖直直线的同时一个优先队列存储能与之产生交点的水平直线有哪些,在线段树中维护它们的纵坐标,于是在线段树中就可以查询交点数了。
Code
1 |
|
F. Reverse and Swap
Solution
考虑线段树维护原序列,设线段树从上往下是第 $0$ 层、第 $1$ 层、……第 $n$ 层。容易发现,$Swap(k)$ 操作就是给第 $n-k-1$ 层的所有节点打上子树交换标记,而 $Reverse(k)$ 操作就是给第 $n-k$ 到第 $n$ 层的所有节点打上子树交换标记。既然如此,我们就记录一下每一层的标记状况,修改或查询的时候按照标记状况决定往左子树还是右子树走——原本该往左子树走的,如果有标记,就往右子树的对应区间走;原本该往右子树走的,如果有标记,就往左子树的对应区间走。换句话说,序列还是原来那个顺序,我们把对序列的操作变成了对操作区间的操作,如此解决问题。
Code
1 |
|
Codeforces Round #665 (Div.2)
http://xyfjason.github.io/blog-xcpc/2020/08/22/Codeforces-Round-665-Div-2/