blog/content/post/算法题/异或和.md
2025-03-10 16:20:26 +08:00

2.8 KiB
Raw Blame History

title description date slug categories tags math
阿里笔试T1异或和与GCD 考查注意力的纯数学“算法题” 2025-03-10T15:29:00+08:00 异或和
算法题
异或
GCD
算法
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;
    }
}