线性基的话,我觉得就是把n个数的排列简化成63个数,使其异或出来的数跟原来可以异或出来的数一样
先把矿石按权值从大到小排序
一个一个往里加
如果加进去的不合法,就放弃它,因为如果选了它,那么比它权值大的矿石就要放弃
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int N=1006;
struct JI
{
ll order;
ll val;
bool friend operator < (JI a,JI b)
{
return a.val>b.val;
}
}ji[N];
ll n;
ll p[68];
ll work()
{
ll ans=0;
sort(ji+1,ji+1+n);
for(int i=1;i<=n;++i)
{
for(int j=62;j>=0;--j)
if( (((ll)1<<j)&ji[i].order) )
{
if(!p[j])
{
p[j]=ji[i].order;
break;
}
ji[i].order^=p[j];
}
if(ji[i].order)
ans+=ji[i].val;
}
return ans;
}
int main(){
//freopen("in.in","r",stdin);
scanf("%lld",&n);
for(int i=1;i<=n;++i)
scanf("%lld%lld",&ji[i].order,&ji[i].val);
cout<<work();
}