#3687. 简单题
内存限制:512 MiB
时间限制:10 Sec
题目描述
小呆开始研究集合论了,他提出了关于一个数集四个问题:
1.子集的异或和的算术和。
2.子集的异或和的异或和。
3.子集的算术和的算术和。
4.子集的算术和的异或和。
目前为止,小呆已经解决了前三个问题,还剩下最后一个问题还没有解决,他决定把
这个问题交给你,未来的集训队队员来实现。
输入格式
第一行,一个整数n。
第二行,n个正整数,表示01,a2….,。
输出格式
一行,包含一个整数,表示所有子集和的异或和。
样例
样例输入
2
1 3
1 3
样例输出
6
数据范围与提示
【样例解释】
6=1 异或 3 异或 (1+3)
【数据规模与约定】
ai >0,1<n<1000,∑ai≤2000000。
另外,不保证集合中的数满足互异性,即有可能出现Ai= Aj且i不等于J
题解:
自己异或两次的话就没有了。。。。。
异或背包 , bitset优化一下;
复杂度: $O(\frac{n \sum a_{i} } {64} $
反正bitset的复杂度比较玄学吧。。。。。。。。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 #include<cmath> 7 #include<vector> 8 #include<stack> 9 #include<map> 10 #include<set> 11 #include<bitset> 12 #define Run(i,l,r) for(int i=l;i<=r;i++) 13 #define Don(i,l,r) for(int i=l;i>=r;i--) 14 #define ll long long 15 #define ld long double 16 #define inf 0x3f3f3f3f 17 using namespace std; 18 int n; 19 bitset<2000100>f; 20 int main(){ 21 freopen("in.in","r",stdin); 22 freopen("out.out","w",stdout); 23 scanf("%d",&n); 24 int x , sum=0; 25 //f.reset(); 26 f[0]=1; 27 Run(i,1,n){ 28 scanf("%d",&x); 29 f^=f<<x; 30 sum += x; 31 } 32 int ans=0; 33 Run(i,1,sum){ 34 if(f[i])ans^=i; 35 } 36 cout<<ans<<endl; 37 return 0; 38 }//by tkys_Austin;