Educational Codeforces Round 164 (Rated for Div. 2)
A. Painting the Ribbon
思路:实际上就是要求最少可以把多少格子染成相同的颜色,只要 ⌈ n m ⌉ \lceil \frac{n}{m} \rceil ⌈mn⌉计算一下就好了。
时间复杂度: O ( 1 ) O(1) O(1)
B. Make It Ugly
思路:题目给定的序列满足如下性质,若 a i − 1 = a i + 1 a_{i-1} = a_{i+1} ai−1=ai+1,那么可以把 a i a_i ai也替换为 a i − 1 a_{i-1} ai−1,现在要求我们删除若干个数来破坏这个性质。实际上是有两种方案的,我们记 a i − 1 a_{i-1} ai−1与 a i + 1 a_{i+1} ai+1这种类型的数为A数, a i a_i ai这种类型的数为B数(被替换掉的数)。一种是移除掉序列一侧所有A数,另一种就是移除两个B数之间所有的A数,然后只要取个最小值就好了。注意到给定序列满足这个性质,所以序列的首尾一定是A数。
时间复杂度: O ( n ) O(n) O(n)
C. Long Multiplication
思路:任意交换两个字符串的若干位使得两个字符串的乘积最大。显然有 x + y = C x+y=C x+y=C, x + y ≥ 2 x y x+y \ge 2\sqrt{xy} x+y≥2xy,当且仅当 x = y x=y x=y时等号成立,所以 x x x与 y y y越接近,那么两者的乘积也就越大。
时间复杂度: O ( n ) O(n) O(n)
D. Colored Balls
思路:一次操作将两种不同颜色的球放到一个集合里,这类似于摩尔投票法。所以实际上每个子集的贡献就是, s i z e + 1 2 \frac{size+1}{2} 2size+1或者$ \max{a_i}$。因为是要计算全集的贡献,所以我们没有必要按照题目给定的要求去枚举所有的集合。我们先假设所有子集的贡献都是前者,那么我们可以按照集合大小求出对于每一种大小的集合的方案数,同等大小的子集贡献是相同的;然后我们来枚举第二种贡献的情况,实际上也是按照集合大小进行枚举,减掉第一种贡献然后加上第二种贡献。
时间复杂度: O ( n Σ a ) O(n\Sigma{a}) O(nΣa)
E. Chain Reaction
思路:直观上来讲,我们可以计算一下当前对整个序列进行一次操作(在上一次操作的基础上再造成一次伤害)需要耗费的代价是什么,然后每次查询时, O ( L n ( n ) ) O(Ln(n)) O(Ln(n))地求(调和级数)。那么怎么求呢,我们按照血量从 1 开始枚举已经造成的伤害,每次都枚举当前这个血量的怪物的位置,实际上就是这个怪物在下一轮我们操作时会消失,假设当次操作没有任何怪物死亡,那么下次造成伤害时的代价一定与当次操作的代价是相同的,接下来考虑变化。如果当前位置两端的怪物都存活,那么代价加一,因为伤害要分开进行;如果当前位置两段的怪物都死亡,那么代价减一,因为不再需要对当前位置的怪物造成伤害了。
详细解释一下怎么利用提到的“当前对整个序列进行一次操作(在上一次操作的基础上再造成一次伤害)需要耗费的代价是什么”在每次查询中计算贡献:现有序列一定的情况下,我们再对当前序列操作一次所产生的代价不受 k k k值影响,所以就可以每次跳跃到将造成伤害的位置统计计算。
时间复杂度: O ( k L n ( n ) ) O(kLn(n)) O(kLn(n))