异或运算
已知一个包含 $n$ 个元素的正整数集合 $S$,设 $f(S)$ 为集合 $S$ 中所有元素的异或(XOR)的结果。 如:$S = \{1, 2, 3\}$, 则 $f(S) = 0$。 给出集合 $S$,你需要计算 将所有 $f(s)$ 进行异或后的值, 这里 $s \subseteq S$.
输入描述
多组测试数据。第一行包含一个整数 $T(T\leq 20)$ 表示组数。 每组测试数据第一行包含一个数 $n(1\leq n \leq 1,000)$ 表示集合的大小,第二行为 $n$ 的数表示集合元素。第 $i(1\leq i \leq n)$ 个数 $0 \leq a_i \leq 1000,000,000$ 且数据保证所给集合中没有重复元素。
输出描述
对于每组测试数据,输出一个数,表示将所有的 $f(s)$ 的异或之后的值。
输入样例
1 3 1 2 3
输出样例
0
Hint
样例中,$S = \{1, 2, 3\}$, 它的子集有$\varnothing$, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}
解题思路:
Problem 1001 我们考虑集合中的每个数x对答案的贡献。设集合有n个数,则包含x的子集个数有2^(n-1)个。那么当n > 1时,x出现了偶数次,所以其对答案的贡献就是0;当 n = 1时,其对答案的贡献是 x
代码:
#include<stdio.h>
#include<string.h>
typedef long long LL;
const int maxn = 1000 + 24;
int main() {
LL kase, n, a[maxn];
scanf("%lld", &kase);
while(kase--) {
scanf("%lld", &n);
LL ans;
for(int i = 0; i < n; ++i) {
scanf("%lld", &a[i]);
}
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
if(i == 0 && j == 0) ans = a[i];
else ans ^= a[i];
}
}
printf("%d\n", ans^0);
}
}(被坑了,没想到)