概述
题意
求 ( a 1 + a 2 ) ⊕ ( a 1 + a 3 ) ⊕ … ⊕ ( a 1 + a n ) ⊕ ( a 2 + a 3 ) ⊕ … ⊕ ( a 2 + a n ) … ⊕ ( a n − 1 + a n ) (a_1 + a_2) oplus (a_1 + a_3) oplus ldots oplus (a_1 + a_n) \ oplus (a_2 + a_3) oplus ldots oplus (a_2 + a_n) \ ldots \ oplus (a_{n-1} + a_n) (a1+a2)⊕(a1+a3)⊕…⊕(a1+an)⊕(a2+a3)⊕…⊕(a2+an)…⊕(an−1+an)
其中 n ≤ 400000 nleq 400000 n≤400000, a i ≤ 1 0 7 a_ileq10^7 ai≤107
分析
这场用手速上了紫嘿嘿嘿,不过
D
D
D 没做出来还是太菜了。
对于这种二进制的题,都是一位一位考虑。这里考虑答案的第
k
k
k 位。
我们将每个数取前
k
k
k 位。现在就是考虑
a
i
+
a
j
a_i+a_j
ai+aj 第
k
k
k 位为
1
1
1 的对数。
第
k
k
k 位为
1
1
1 只有两种情况:
- 第
k
k
k 位为
1
1
1,第
k
+
1
k+1
k+1 位为
0
0
0
这种情况就是大于 2 k − a i 2^k-a_i 2k−ai 的个数减去大于 2 k + 1 − a i 2^{k+1}-a_i 2k+1−ai 的个数 - 第
k
k
k 位和第
k
+
1
k+1
k+1 位都为
1
1
1
这种情况就是大于 2 k + 2 k + 1 − a i 2^k+2^{k+1}-a_i 2k+2k+1−ai 的 a j a_j aj 个数
加起来就是第
k
k
k 位为
1
1
1 的对数了。
二分找个数复杂度
O
(
l
o
g
n
)
O(logn)
O(logn)
总共 26 位
复杂度
O
(
26
n
l
o
g
n
)
O(26nlogn)
O(26nlogn)
代码如下
#include <bits/stdc++.h>
#define N 400005
using namespace std;
int a[N], b[N], n;
int get(int l, int x){
if(b[n] < x) return 0;
int r = n, mid;
while(l < r){
mid = l + r >> 1;
if(b[mid] >= x) r = mid;
else l = mid + 1;
}
return n - l + 1;
}
int main(){
int i, j, m, sum, ans = 0;
scanf("%d", &n);
for(i = 1; i <= n; i++) scanf("%d", &a[i]);
for(j = 0; j <= 26; j++){
for(i = 1; i <= n; i++) b[i] = a[i] & ((1 << j + 1) - 1);
//printf("%d======n", j);
//for(i = 1; i <= n; i++) printf("%d ", b[i]);
//printf("n");
sort(b + 1, b + i);
sum = 0;
for(i = 1; i < n; i++){
sum = (sum + get(i + 1, (1 << j) - b[i])) % 2;
sum = (sum - get(i + 1, (1 << j + 1) - b[i])) % 2;
sum = (sum + get(i + 1, (1 << j) + (1 << j + 1) - b[i])) % 2;
}
//printf("sum === %dn", sum);
if(sum % 2) ans |= (1 << j);
}
printf("%d", ans);
return 0;
}
最后
以上就是雪白星月为你收集整理的codeforces1323D Present的全部内容,希望文章能够帮你解决codeforces1323D Present所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复