[Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics)] -D. Present
以下说到的 位数 均指二进制位数
按位讨论每对(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;
}

浙公网安备 33010602011771号