3妹:2哥,你有没有看到新闻“18岁父亲为4岁儿子落户现身亲子鉴定”
2哥 : 啥?18岁就当爹啦?
3妹:确切的说是14岁好吧。
2哥 : 哎,想我30了, 还是个单身狗。
3妹:别急啊, 2嫂肯定在某个地方等着你去娶她呢。又不是结婚越早越好。
2哥:是啊, 这孩子14岁当爹,也太早了。
3妹:2哥,你找女朋友有什么条件没有哇?
2哥 : emmm, 以前希望找一个温柔漂亮的, 现在嘛, 女的、活的。毕竟年龄已经很大了, 已经30了…
3妹:才30而已嘛, 女生很多都喜欢找个比自己大一点的~
2哥 : 哎,你们女生最大能接受比自己大多少岁啊?
3妹:emmm, 这么不好说,要看具体女生,一般大个3-5岁都可以吧。 2哥说到最大, 我今天看到一个最大异或乘积的题目,让我也来考考你吧~
题目:
给你三个整数 a ,b 和 n ,请你返回 (a XOR x) * (b XOR x) 的 最大值 且 x 需要满足 0 <= x < 2n。
由于答案可能会很大,返回它对 109 + 7 取余 后的结果。
注意,XOR 是按位异或操作。
示例 1:
输入:a = 12, b = 5, n = 4
输出:98
解释:当 x = 2 时,(a XOR x) = 14 且 (b XOR x) = 7 。所以,(a XOR x) * (b XOR x) = 98 。
98 是所有满足 0 <= x < 2n 中 (a XOR x) * (b XOR x) 的最大值。
示例 2:
输入:a = 6, b = 7 , n = 5
输出:930
解释:当 x = 25 时,(a XOR x) = 31 且 (b XOR x) = 30 。所以,(a XOR x) * (b XOR x) = 930 。
930 是所有满足 0 <= x < 2n 中 (a XOR x) * (b XOR x) 的最大值。
示例 3:
输入:a = 1, b = 6, n = 3
输出:12
解释: 当 x = 5 时,(a XOR x) = 4 且 (b XOR x) = 3 。所以,(a XOR x) * (b XOR x) = 12 。
12 是所有满足 0 <= x < 2n 中 (a XOR x) * (b XOR x) 的最大值。
提示:
0 <= a, b < 250
0 <= n <= 50
思路:
位运算,
详细见代码:
java代码:
class Solution {
public int maximumXorProduct(long a, long b, int n) {
if (a < b) {
// 保证 a >= b
long temp = a;
a = b;
b = temp;
}
long mask = (1L << n) - 1;
long ax = a & ~mask; // 第 n 位及其左边,无法被 x 影响,先算出来
long bx = b & ~mask;
a &= mask; // 低于第 n 位,能被 x 影响
b &= mask;
long left = a ^ b; // 可分配:a XOR x 和 b XOR x 一个是 1 另一个是 0
long one = mask ^ left; // 无需分配:a XOR x 和 b XOR x 均为 1
ax |= one; // 先加到异或结果中
bx |= one;
// 现在要把 left 分配到 ax 和 bx 中
// 根据基本不等式(均值定理),分配后应当使 ax 和 bx 尽量接近,乘积才能尽量大
if (left > 0 && ax == bx) {
// 尽量均匀分配,例如把 1111 分成 1000 和 0111
long highBit = 1L << (63 - Long.numberOfLeadingZeros(left));
ax |= highBit;
left ^= highBit;
}
// 如果 a & ~mask 更大,则应当全部分给 bx(注意最上面保证了 a>=b)
bx |= left;
final long MOD = 1_000_000_007;
return (int) (ax % MOD * (bx % MOD) % MOD); // 注意不能直接 long * long,否则溢出
}
}