2.8 KiB
2.8 KiB
title | description | date | slug | categories | tags | math | ||||
---|---|---|---|---|---|---|---|---|---|---|
阿里笔试T1:异或和与GCD | 考查注意力的纯数学“算法题” | 2025-03-10T15:29:00+08:00 | 异或和 |
|
|
true |
有一个长度为$n$的数组$a$,数组中每个元素都是整数,取值范围是$[0, 10^{9}]$。设$b$是$a$的一个子数组。
定义$b$的异或和为$b$中所有元素的异或运算结果,即$f(b) = b[0] \oplus b[1] \oplus \cdots \oplus b[k]$。
定义$b$的GCD为$b$中所有元素的最大公约数,即$g(b) = GCD(b[0], b[1], \cdots, b[k])$。
你可以从$a$中选择任意一个子数组$b$,满足$f(b) \cdot g(b)$尽可能大吗?请你算一算这个最大值。
这题其实用了一个结论:
\boxed{\max \{ f(b) \cdot g(b) \} = (\max a_i)^2}
也就是说,所求最大值的平方就是数组最大元素的平方,与数组的元素分布无关。我们来证明一下:
证明
对于任意子数组 $b$,设其最大元素为 $M$,则有重要结论:
f(b) \triangleq b_0 \oplus b_1 \oplus \cdots \oplus b_k < 2M
即一个数组的异或和严格小于最大元素的2倍。
这部分的证明:
- 设
M
的二进制最高位为第k
位(即 $M \in [2^k, 2^{k+1})$)。 - 异或操作的每一位结果独立,最高位为1的次数若为奇数次,则结果最高位为1;否则为0。
- 无论奇偶,异或和的最高位不可能超过
k+1
位,即严格小于 $2^{k+1} \leq 2M$。
我们再分析 g(b)
的上界。子数组的 GCD 满足:
- 如果$b$的元素都相同,则$g(b) = M$。
- 如果$b$的元素不全相同,则 $\displaystyle g(b) \leqslant \frac{M}{2}$。
这个也很好证明。如果全相同,显然成立。如果不全相同,由于一个数的最大因数(除这个数本身)不大于这个数的一半,所以数组的最大公约数不大于最大元素的一半。
那么,现在有两种情形:
- 如果子数组的元素都相同,则:
- 当$n$为偶数时,$f(b) = 0$,$g(b) = M$,$f(b) \cdot g(b) = 0$。
- 当$n$为奇数时,$f(b) = M$,$g(b) = M$,$f(b) \cdot g(b) = M^2$。
- 如果子数组的元素不全相同,则:
- $f(b) < 2M$,$\displaystyle g(b) \leqslant \frac{M}{2}$,$f(b) \cdot g(b) < M^2$。
这就证明了:
\max \{ f(b) \cdot g(b) \} = M^2
只需取子数组为单元素 $M$,即可达到理论最大值。
用到的结论
- 一个正整数数组的异或和严格小于最大元素的2倍。
- 一个正整数数组的最大公约数不大于最大元素的一半。
代码
public class Solution {
public static int maxXorGcd(int[] a) {
int max = 0;
for (int i = 0; i < a.length; i++) {
max = Math.max(max, a[i]);
}
return max * max;
}
}