📅  最后修改于: 2023-12-03 15:11:40.675000             🧑  作者: Mango
本篇介绍一个解决给定范围内所有偶数的XOR的问题的算法。
给定一个区间 $[l, r]$,求范围内所有偶数的异或和。
假设 $n\in[l,r]$ 中有 $m$ 个偶数,则只需求出 $\dfrac{m}{2}$ 个数的异或和即可。因为 $a\oplus a=0$,$a\oplus 0=a$,所以偶数异或自身等于 $0$,而偶数与奇数异或不为 $0$。因此可以将所有偶数的异或和转化为 $\dfrac{m}{2}$ 个数的异或和。
由于异或运算满足结合律和交换律,将这 $\dfrac{m}{2}$ 个数按照二进制位分别异或,即可求得答案。具体来说,设这 $\dfrac{m}{2}$ 个数的二进制位在第 $i$ 位上的值的异或和为 $x_i$,则答案即为:
$$ ans=\sum_{i=0}^{\log_2 r}(x_i\cdot 2^i) $$
其中 $\log_2 r$ 表示 $r$ 的二进制表示中最高位的位置。注意到一个偶数的二进制表示下最低位的值为 $0$,因此要将枚举范围从 $0$ 开始。
该算法的时间复杂度为 $O(\log r)$,其中 $r$ 表示给定区间的右端点。
下面是该算法的 C++ 实现。
long long even_xor(int l, int r) {
long long res = 0;
for (int i = 0; i < 64; ++i) {
int cnt = (r >> (i + 1) << 1) - (l >> (i + 1) << 1);
if (cnt & 1) res += (1LL << i);
}
return res;
}
本篇介绍了一种求解给定范围内所有偶数的异或和的算法。这是一道很有思维难度的题目,需要将异或运算的性质结合二进制位的性质进行巧妙的转化。