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\)个最小值,结论依然成立。