1. 程式人生 > >【bzoj3687】簡單題

【bzoj3687】簡單題

#3687. 簡單題

記憶體限制:512 MiB 時間限制:10 Sec 提交 提交記錄 討論

題目描述

小呆開始研究集合論了,他提出了關於一個數集四個問題:
1.子集的異或和的算術和。
2.子集的異或和的異或和。
3.子集的算術和的算術和。
4.子集的算術和的異或和。
    目前為止,小呆已經解決了前三個問題,還剩下最後一個問題還沒有解決,他決定把
這個問題交給你,未來的集訓隊隊員來實現。

輸入格式

第一行,一個整數n。
第二行,n個正整數,表示01,a2….,。

輸出格式

一行,包含一個整數,表示所有子集和的異或和。

樣例

樣例輸入

2
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;
View Code