luogu4570
题目大意
有\(n(1≤N≤1000)\)块魔法石用来制作魔法杖。每块魔法石都有编号和魔法能量,如果编号异或为0则能量抵消为0,问最大可以获得的能量是多少(魔法能量求和)?
输入格式
第一行包含一个正整数 \(N\),表示矿石的种类数。
接下来 \(N\) 行,每行两个正整数\(\mathrm{Number}_i\)和 \(\mathrm{Magic}_i\) ,表示这种矿石的元素序号和魔力值。
输出格式
仅包含一行,一个整数代表最大的魔力值。
输入输出样例
输入
3
1 10
2 20
3 30
输出
50
当多个数异或成为0时,肯定有一个不能加入。明显去掉的应该是魔法能量最小的那个。
所以,先对所有的魔法石按照魔法能量从大到小排序,让后依次来取,如果加入会异或为0则不加入。线性基判断是否可以加入!
#include<bits/stdc++.h>
using namespace std;
const int maxn=1010;
typedef long long ll;
int n;
struct node
{
ll no,mg;
}sz[maxn];
ll d[70];
bool cmp(node a,node b)
{
return a.mg>b.mg;
}
ll ans;
bool insert(ll x)
{
for(int i=63;i>=0;--i)
if(x&(1ll<<i))
{
if(d[i])x^=d[i];
else
{
d[i]=x;
return 1;
}
}
return 0;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%lld%lld",&sz[i].no,&sz[i].mg);
sort(sz+1,sz+1+n,cmp);
for(int i=1;i<=n;++i)
if(insert(sz[i].no))ans+=sz[i].mg;
cout<<ans<<endl;
return 0;
}