[线性基 贪心] 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(;;);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值