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;
}

posted on 2021-08-04 10:55  gryzy  阅读(45)  评论(0编辑  收藏  举报

导航