Codeforces 题目选讲 1
文章目录
本文主要讲解一些近期遇到的一些有启发意义的 Codeforces 题目。不定时更新。
Anu Has a Function
定义。
给你一个长度为的序列,你可以随意安排顺序,最小化
。
摘要:理解位运算。
容易发现。相当于在中把属于的部分挖掉。
因此的值只和的值有关。
把复杂度做到即可。
Aerodynamic
给你一个凸多边形。
定义凸多边形函数:
- 随便固定一个点。
- 在保证(即在的边界或内部)的情况下随便平移,尽可能经过多的点(覆盖多的面积)。所经过的点的集合构成多边形。
问与是否相似。
。
摘要:大力猜结论。
如果是正三角形的话,就是正六边形。
容易发现,当是奇数时有条边,与不相似。
为了不产生多余的边,就要求的对边平行且相等(第条边和第条边平行且相等)。感性理解不难。
大力猜想这是重要条件。
复杂度。
Water Balance
给你一个长度为的序列。每次你可以把的元素都变成(变成平均数)。
问能操作出的字典序最小的序列是啥。
。
摘要:贪心,复杂度均摊。
由于是字典序最小,因此我们从前往后依次考虑。
如果就不管。
如果,显然我们一定会以为左端点做一次操作。但是这次操作的区间有多长?我们可以一直向右延伸,如果平均值变小就延伸,如果变大就停止延伸,然后把这段区间给操作一次。
操作完之后,我们还可以找到,如果,就把左端点往左延伸一点然后进行一次操作。毕竟我们要求字典序最小。直到不存在的情况位置。
然后我们跳过这一段区间做后面的事。
但事实上这么做了一轮之后不一定字典序就最小了。还可以做第二轮第三轮。
可以使用链表缩点优化。
稍作感知,认为做的次数不会很多。
Animal Observation
题面较长。但样例的图十分可读。
摘要:DP 优化。
设表示前行,其中第行选择从第列开始的矩形(占据两行)的最大值。
从转移。
从转移。根据的关系可以分类讨论。
容易发现,使用前缀,后缀和单调队列就可以分别优化了。
时间复杂度。
Cow and Fields
给你一个个点条边的无向简单图。有个关键点。要求你必须在个关键点中选择两个点连一条边。
最大化到的最短路。
。
摘要:转化为数学模型。
设表示到的最短路,表示到的最短路。
对于两个关键点,如果加入并强制走这条边,则最短路是。
因此我们要求的是
不妨设,即,则我们要求的是
可以前缀后缀在的时间统计出来(算上了排序的时间)
然后再和比较一下即可。
时间复杂度。
Cow and Treats
题面较长
摘要:观察,分析,发现左边和右边不能相交。于是枚举分割位置然后计算。
观察发现:
- 同一种颜色(sweetness)最多选 2 头牛(分别从左右两个方向出发)。
- 左边走的最远的牛和右边走的最远的牛不能碰面。
- 一但安排好了两个集合,只要满足上面两个条件,那么一定可以按要求使得所有牛都睡觉。
于是我们枚举左边的牛走的最远的走到哪里。然后对每个颜色统计放的最多的方案数并更新答案即可。
Cow and Vacation
给一个个点的树,有个休息点(关键点)。你在不休息的情况下最多连续走条边。你走到一个休息点后就可以休息好,继续走最多条边。次询问,能否从走到。
摘要:两边 BFS,并查集。
一开始想了一个虚树 + 并查集 + 点分治的思路,难想又难写。所以就不讲了。
基本的思路是:我们把距离休息点以内的点和休息点 merge。那么如果两个休息点距离小于等于,他们就会 merge 到一起。询问的时候先判距离以及是否在同一个集合。否则就相向而行各走步。如果走到这里了都不能走到一个集合里,说明不行(注意,我们是把距离休息点以内的点和休息点 merge 过的,因此如果走步后不能走到一个休息点上,就说明不行)。
merge 就用并查集做。我们事先把每条边中间加一个二度点(距离乘),这样就不用考虑的奇偶性了。然后走步的时候相当于倍增跳祖先。
时间复杂度。
Reachable Strings
对于一个 01 串你可以进行以下两种操作:
- 选择一个
110
并将其替换为011
;- 选择一个
011
并将其替换为110
;给你一个串,有次询问,问你能否通过若干次操作变成。
。
摘要:根据一段 1 个数的奇偶性给 0 分段。然后做字符串匹配(哈希或者 SA)。
上面的操作可以理解为是,一段偶数个 1 可以随意穿梭在 0 之中。因此我们把连续的偶数个 1 可以直接删掉。那么就剩下了一个 01 串使得每一段连续的 1 只有一个 1。
那么我们把每段 0 的个数写成一个序列,这就等价于问你两个序列是否相等。
可以使用 SA 或者哈希计算。
时间复杂度或。
考场上抽风,写了一个线段树 + 哈希,最后还没交上去,不知道在想啥。
代码 仅供对拍,不建议学习。
Treeland and Viruses
题面较长。
摘要:建虚树,跑多源最短路。
注意,最短路以到达时间(不是路程)为第一关键字,病毒编号为第二关键字。
Kuroni and the Score Distribution
给出。构造长度为的序列满足:
- 。
- 。
。
摘要:构造。
当时做这题时,读错题了,以为是求构造的方案数。把我自闭了半小时。
首先思考,如何构造使得最大化?构造即可。
因此我们依次构造,让的数量接近。然后把下一个数字稍微改一下使得刚好凑出。然后我们要求剩下的数字不能有任何的情况出现。那么构造即可。乘的原因是避免与前面构造的产生。
无解的情况稍微判一下。
Kuroni and the Punishment
给出长度为的序列,要求你构造长度为的正整数序列使得,且最小化。
求出这个最小化的。
。
摘要:乱搞。
如果确定了,那么我们可以求出最小的。
令,易得。因此若,一定是某个的约数。同时易证,存在是质数(质因子)的最优解。
好接下来开始乱搞。我们的大致思路是随机几个质数出来更新答案。但是不能乱随。
由于,因此我们就随机几个,把的质因子都拿出来更新答案。
可以证明,错误的概率是指数级减小的()。
要去重后再更新。
Kuroni and Antihype
有个数和一个集合。你可以进行两种操作:
- 把()加入,没有奖励;
- 选择中的一个数和不在中的一个数,且,把加入,奖励为。
要求你把都加入到中,求出最大化的奖励的和。
。
设,一开始中有。那么所有的 1 操作可以转化为的 2 操作。
容易发现,所有的 2 操作构成一个以为根的有根树。
设树上结点的度为。那么我们的奖励显然为。
注意到。
考虑最大化。这等价于加权无向图
中的最大生成树的边权和(注意,这和上文中的有根树没有任何关系,因为我们已经把问题转化为最大化了)。
考虑使用 Boruvka 算法 求最大生成树。
那么我们的问题转化为,如何求与相邻的权值最大的边且不在同一连通块。可以使用子集前缀和解决,记表示满足且最大的,表示次大的,记作,且不在同一连通块。这个可以 FMT 求出。然后我们就可以求出与相邻的权值最大的边了。
时间复杂度,其中,表示值域。
修订记录
- 2020年3月4日 创建文章