51nod 1312 最大异或和(线性基)

线性gay - - 

分析:要求和尽量大,首先可以想到,求完线性基后,记最大异或为Max,对于线性基以外的数,都可以变成Max,剩下的线性无关,变成最小线性基,可以通过异或基中最大的数把所有的最高位变成1,这样显然是最优的,然后把最大的数异或成Max,去掉这个数后再考虑剩下的数,以此类推,相当于最大的数取Max,其它的取Max ^ 自己,加起来就是答案。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 const int maxn = 55;
 6 typedef long long ll;
 7 struct LinearGay{
 8     ll a[64], have;
 9     int n, high_bit;
10     LinearGay(){
11         memset(a, 0, sizeof(a));
12         n = have = high_bit = 0;
13     }
14     void insert(ll x){
15         int d = 63;
16         while(x && d >= 0){
17             if(x & (1LL << d)){
18                 if(a[d]){
19                     x ^= a[d];
20                 }
21                 else{
22                     a[d] = x;
23                     high_bit = max(d, high_bit);
24                     n++;
25                     break;
26                 }
27             }
28             d--;
29         }
30     }
31     void Minimize(){
32         for(int i = 63; i >= 0; i--){
33             if(!a[i])continue;
34             for(int j = i - 1; j >=0; j--){
35                 if(!a[j])continue;
36                 a[i] = min(a[i], a[i] ^ a[j]);
37             }
38         }
39     }
40     ll MaxXor(){
41         Minimize();
42         ll res = 0;
43         for(int i = 63; i >= 0; i--){
44             if(a[i])res ^= a[i];
45         }
46         return res;
47     }
48 }lb;
49 int main(){
50 //    freopen("e:\in.txt","r",stdin);
51     int n;
52     cin>>n;
53     ll a;
54     for(int i = 0; i < n; i++){
55         cin>>a;
56         lb.insert(a);
57     }
58     ll Max = lb.MaxXor();
59     ll ans = 0;
60     for(int i = 0; i < lb.high_bit; i++){
61         if(lb.a[i])ans += Max ^ lb.a[i];
62     }
63     ans += (n - lb.n + 1) * Max;
64     cout<<ans<<endl;
65     return 0;
66 }
原文地址:https://www.cnblogs.com/7391-KID/p/7811728.html