以下说到的 位数 均指二进制位数
按位讨论每对(a[i], a[j])对答案第i位的贡献
log2(1e7) 上取整 24 位
影响第i位的,只有 0~i 位
当a[i] 位为 1 时,能对 答案第i位贡献 1的 就是 a[j](第i位位0 且 0~(i-1)位与a[i]相加不进位)或者 (第i位为 1 且 0 ~(i-1)相加进位)
当 a[i] 位为 0 时, a[j] (第i位为 1 且 0 ~ (i- 1)相加不进位),或者 (第i位为 0,且 0 ~ (i- 1)相加进位 )
由于复杂度原因,要二分查找,那么我们求i位的时候都要排序,怎么排?b[i] = a[i] % (1 << i + 1) ,排序b即可,
其他细节计数,见代码
#include <bits/stdc++.h> #define ll long long using namespace std; const int maxn = 1e7 + 5; int n, a[maxn], res, b[maxn]; int main() { scanf("%d", &n); for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); for (int i = 0; i <= 24; ++i) { int mod = 1 << i + 1, ans = 0; for (int j = 1; j <= n; ++j) b[j] = a[j] % mod; sort(b + 1, b + 1 + n); for (int j = 1; j <= n; ++j) { if (b[j] & (1 << i)) { int l = lower_bound(b + 1 + j, b + 1 + n, (1 << i + 1) - b[j]) - b; int r = lower_bound(b + 1 + j, b + 1 + n, (1 << i + 1) - (b[j] ^ (1 << i))) - b; ans += l - j + n - r; } else { int r = lower_bound(b + 1 + j, b + 1 + n, (1 << i + 1) - b[j]) - b; int l = lower_bound(b + 1 + j, b + 1 + n, (1 << i) - b[j]) - b; ans += r - l; } } if (ans & 1) res ^= 1 << i; } printf("%d", res); scanf("%d", &n); return 0; }