CF1322B - Present
题意
个数 ,现在求 ,
题解
直接算是不行的
这里考虑计算二进制下
的每一位
对于
的第
位答案,我们只需要考虑数
的
位,因为超过
位对第
位没有影响
所以我们记
,这样就保留了
位的影响
然后我们要第
位结果是
的
而第
位为1的数的范围为
和
后面
这么来的:
,这里两个数,所以就是
可以通过枚举
求得对应的
数量即可
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX = 4e5 + 10;
int N;
int a[MAX], b[MAX];
int pos(int x) { return lower_bound(b + 1, b + 1 + N, x) - b; }
int main() {
scanf("%d", &N);
for (int i = 1; i <= N; i++) scanf("%d", &a[i]);
int ans = 0;
for (int bit = 0; bit <= 25; bit++) {
int num = 1 << bit;
for (int i = 1; i <= N; i++) b[i] = (a[i] & (2 * num - 1));//和a[i] % (2 * num - 1)一样的
sort(b + 1, b + 1 + N);//排序
int cnt = 0;
for (int i = 1; i <= N; i++) {
cnt += pos(4 * num - b[i] - 1) - pos(3 * num - b[i]);//[3 * num, 4 * num - 2]间的数
cnt += pos(2 * num - b[i]) - pos(num - b[i]);//[num, 2 * num - 1]间的数
if ((2 * b[i]) & num) cnt--;//如果b[i]+b[i]的第k位是1, 就减去这种
}
if ((cnt / 2) & 1) ans ^= 1 << bit;//这里cnt/2是因为我们会算b[i]+b[j]和b[j]+b[i]两种
}
printf("%d\n", ans);
return 0;
}