【题解提供者】吴立强
解法
思路
首先,暴力计算提交后会 TLE。
其次,注意到 x ⊕ y ⊕ y = x x\oplus y \oplus y = x x⊕y⊕y=x(这里 ⊕ \oplus ⊕ 代表异或操作)。
最后,可以考虑使用前缀和算法,类比做出【异或前缀和】用于快速求解区间异或值。
代码展示
#include <iostream>
using namespace std;
const int N = 1000009; /// 定义常量用于开辟数组空间
int a[N];
int main() {
int t; cin >> t;
/// 预处理出 [0, 1e6] 的前缀异或和
for(int i = 1; i <= 1000000; i ++) a[i] = a[i - 1] ^ i;
while(t --) {
int l, r; cin >> l >> r;
/// 利用【异或】和【前缀异或和】凑出对应区间的答案,小心数组越界
cout << (a[l == 0 ? 0 : l - 1] ^ a[r]) << endl;
}
return 0;
}
算法分析
程序时间复杂度为 O ( 1 0 6 + t ) O(10^6 + t) O(106+t)。
拓展
可以注意到连续数异或操作具有特殊性质:
- [ 0 , 1 , 2 , 3 ] , [ 4 , 5 , 6 , 7 ] , [ 8 , 9 , 10 , 11 ] , . . . , [ x , x + 1 , x + 2 , x + 3 ] , . . . [0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], ..., [x, x+1, x+2, x+3], ... [0,1,2,3],[4,5,6,7],[8,9,10,11],...,[x,x+1,x+2,x+3],...( x m o d 4 = 0 x \mod 4 = 0 xmod4=0)
- 上述区间,4 个一组,且每一组中的数的异或值都为 0。