[線性基 貪心] Topcoder SRM557Div1. XorAndSum

對數列建線性基,求出最大異或值

那麼不在線性基裏面的元素可以把它變成最大異或值

在線性基裏的元素,可以把最高位的元素變成最大值,然後把其他數異或上最大值

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>

using namespace std;

typedef long long ll;

const int N=55;

int n;
ll a[N];
ll b[N];

void add(ll x){
  for(int i=50;~i;i--)
    if(x>>i&1){
      if(!b[i]){
    b[i]=x;
    for(int j=0;j<i;j++)
      if(b[i]>>j&1) b[i]^=b[j];
    for(int j=50;j>i;j--)
      if(b[j]>>i&1) b[j]^=b[i];
    return; 
      }
      x^=b[i];
    }
}

class XorAndSum{
public:
  ll maxSum(vector<ll> number){
    n=number.size();
    for(int i=0;i<n;i++) a[i+1]=number[i];
    for(int i=1;i<=n;i++) add(a[i]);
    int cnt=0,lst=0;
    for(int i=0;i<=50;i++)
      cnt+=!!b[i],lst=b[i]?i:lst;
    ll Max=0;
    for(int i=0;i<=50;i++) Max^=b[i];
    ll ret=Max*(n-cnt+1);
    for(int i=lst-1;~i;i--)
      if(b[i]) ret+=Max^b[i];
    return ret;
  }
}Main;

int main(){
  vector<ll> a={27479, 32870, 34306, 34836, 34350, 26420, 32594, 33068, 31770, 27536, 30467, 27838, 35378, 36884, 36742, 38726};
  cout<<Main.maxSum(a)<<endl;
  for(;;);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章