1. 程式人生 > >51nod 1312 最大異或和(線性基)

51nod 1312 最大異或和(線性基)

ans cst image 就是 xor return ++ amp nbsp

技術分享

線性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 }

51nod 1312 最大異或和(線性基)