Codeforces Round #781 (Div. 2)

比赛链接

A. GCD vs LCM

1, n - 3, 1, 1

B. Array Cloning Technique

首先,最后全部相等的元素,肯定是选初始时出现次数最多的元素,记该元素为\(x\),其出现次数为\(c\)

然后每次复制,都是新的拷贝中,所有的\(x\)都拷回原数组。这里,易得把数拷回原数组的操作共有\(n - c\)次,然后只剩拷贝的操作了。

第一次复制出来的数组中包含\(c\)\(x\),第二次包含\(2c\)个,第三次包含\(4c\)个,以此类推。

然后模拟一下就好了。

C. Tree Infection

首先,这题只和每个节点的子节点个数有关,将所有非叶子节点的儿子个数记录下来,注意还有根节点也要算1次。

然后,先infect的点后续可以借助spread白嫖,所以排个序,贪心先搞儿子个数多的。

然后求最小值就跑个二分。

注意每次spread只能搞一个,就算这个集合中被多次infect了。

D. GCD Guess

比赛的时候就差最后一步没想明白,错失上分机会。

首先,从低位开始,每次确定\(x\)的一个位,这样是可以在30轮内完成的。

对于第\(1\)轮,\(a=2,b=4\)\(gcd(x+a, x+b) = gcd(x+a, b - a) = gcd(x + a, 2)\),如果返回结果为\(2\)说明\(x\)最低一位为0,反之为1。

对于第\(i\)轮,\(x\)的低\(i - 1\)位已经确定了,现在要确定其第\(i\)位。令\(a = 2^i - (x \mod 2^i)\)\(b = a + 2^i\)\(gcd(x+a,x+b) = gcd(x + a, b -a) = gcd(x + a, 2^i)\),如果返回结果为\(2^i\)说明\(x\)\(i\)位为0,反之为1。

但是这个做法在最后一轮的时候会因为\(b\)超过\(10^9\)挂掉,所以需要特判。

本来想着用\(gcd(2x,3x) = x\)来判断,但是发现\(3x\)会超出\(10^9\),所以改用\(gcd(x + 1, 2x + 2) = x+1\)来判断。

E. MinimizOR

可以证明,区间\([l, r]\)的答案,一定是在其中最小的\(31\)个值数产生,找到区间最小的31个数,枚举两两或的结果,取最小值即为答案。

区间最小值可以想到线段树,然后最小的31个数可以每次取完最小就将对应位置改为无穷大,这样通过31次取最小和单点修改操作就可以获取最小的31个数,然后算完结果再恢复回去。

证明

命题:如果区间内最大值小于\(2^k\),那么区间内的答案一定是在其中最小的\(k+1\)个数中产生。

可以用归纳法证明。

  • \(k=1\)的时候显然成立。

  • 假设对于\(k\)成立,则对于\(k+1\)

    • 如果区间内的数,第\(k+1\)位全为1,那么答案的第\(k +1\)位为1。答案和只考虑后\(k\)位一样,结论成立。
    • 如果区间内的数,有大于等于2个第\(k+1\)位为0,那么答案的第\(k+1\)为为0。此时我们只需要考虑第\(k+1\)位为0的数,前\(k\)位小的数前面加上0还是小,所以结果还是会在之前选出来的最小值中,结论成立。
    • 如果区间内的数,只有1个第\(k+1\)位为0,那么答案的第\(k +1\)位为1。此时,之前的候选可能和这个第\(k+1\)位为0的数产生新的答案,所以将其加入最小值集合,现在是\(k+2\)个最小值,结论依然成立。
posted @ 2022-04-10 16:32  _Backl1ght  阅读(37)  评论(0编辑  收藏  举报