已知一个包含 nn 个元素的正整数集合 SS,设 f(S)f(S) 为集合 SS 中所有元素的异或(XOR)的结果。 如:S = \{1, 2, 3\}S={1,2,3}, 则 f(S) = 0f(S)=0。 给出集合 SS,你需要计算 将所有 f(s)f(s) 进行异或后的值, 这里 s \subseteq Ss⊆S.
多组测试数据。第一行包含一个整数 T(T\leq 20)T(T≤20) 表示组数。 每组测试数据第一行包含一个数 n(1\leq n \leq 1,000)n(1≤n≤1,000) 表示集合的大小,第二行为 nn 的数表示集合元素。第 i(1\leq i \leq n)i(1≤i≤n) 个数 0 \leq a_i \leq 1000,000,0000≤ai≤1000,000,000 且数据保证所给集合中没有重复元素。
对于每组测试数据,输出一个数,表示将所有的 f(s)f(s) 的异或之后的值。
1 3 1 2 3
0
样例中,S = \{1, 2, 3\}S={1,2,3}, 它的子集有\varnothing∅, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}
这里粘上BC给的题解吧:
我们考虑集合中的每个数x对答案的贡献。 设集合有n个数,则包含x的子集个数有2^(n-1)个。 那么当n > 1时,x出现了偶数次,所以其对答案的贡献就是0;当 n = 1时,其对答案的贡献是 x。
挺简单的题,可惜当时没做出来 =。=
代码如下:
#include <cstdio> #include <queue> #include <algorithm> using namespace std; int main() { int u; int n; int num[1111]; int ans; scanf ("%d",&u); while (u--) { scanf ("%d",&n); for (int i = 1 ; i <= n ; i++) scanf ("%d",&num[i]); if (n == 1) printf ("%d\n",num[1]); else printf ("0\n"); } return 0; }