51nod 1312 最大异或和(线性基)
Posted 7391_KID
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
以上是关于51nod 1312 最大异或和(线性基)的主要内容,如果未能解决你的问题,请参考以下文章