题目:
给你三个整数 a ,b 和 n ,请你返回 (a XOR x) * (b XOR x) 的 最大值 且 x 需要满足 0 <= x < 2n。
由于答案可能会很大,返回它对 109 + 7 取余 后的结果。
注意,XOR 是按位异或操作。
题解:
XOR的定义:对于两个二进制位,如果相同则结果为0,不同则结果为1。
先不看n只看a和b,ax和bx越大肯定越好,当a和b一个位相同时,x只要取反就能取得a和b该位上的1,当一个位不相同时(其中一个为0,另外一个为1),这里需要考虑分配给a还是b。首选能想到的时这个1不论分配给谁,ax+bx = 定值,根据均值定理,a与b越接近,乘积也就越大。这里需要考虑怎么分配1,减少ax和bx的差距。
现在我们假设a>b,分情况讨论:
情况1:a和b的高位都相等,把最高位的1分配给其中一个,其他的只能分配给另外一个
情况2:a和b的高位不相等,无论怎么分配,a永远比b要大,所以需要把所有1分配给b
常用运算技巧:
集合运算:
集合与元素:
函数库:
最后代码:
点击查看代码
public int maximumXorProduct(long a, long b, int n) {
int mod = (int) (Math.pow(10, 9) + 7);
if (a < b) {
long tmp = a;
a = b;
b = tmp;
}
long mask = (1L << n) - 1;
//取不变的高位
long ax = a & ~mask;
long bx = b & ~mask;
//保留低位
a &= mask;
b &= mask;
//不同的部分
long diff = a ^ b;
//相同的部分
long same = diff ^ mask;
//加入相同的部分
ax |= same;
bx |= same;
//有不同的部分需要分配
if (diff > 0 && ax == bx) {
//高位给a
long highBit = 1L << (64 - Long.numberOfLeadingZeros(diff) - 1);
ax |= highBit;
//从diff中移除
diff ^= highBit;
}
//剩下的给b
bx |= diff;
ax %= mod;
bx %= mod;
return Math.toIntExact((ax * bx) % mod);
}