题意:
一个矿石组合会产生“魔法抵消”当且仅当存在一个非空子集,那些矿石的元素序号按位异或起来为零。合成出来的法杖的魔力等于每一种矿石的法力之和。求可以炼制出的法杖最多有多大的魔力。
题解:
贪心+线性基。
因为线性基中一定没有子集异或是0的。
简要证明:用反证法,假设线性基中:
a1 xor a2 xor……am=0
那么:
a2 xor……am=a1
a1 就是多余的了,不符合线性基的定义。
所以就按法力值排序,从大到小插入线性基就行了。
code:
#include<cstdio>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
struct node{
LL a,x;
}a[1010];
LL n,ans=0;
LL b[65];
bool cmp(node a,node b) {return a.a>b.a;}
int main()
{
scanf("%lld",&n);
for(LL i=1;i<=n;i++) scanf("%lld %lld",&a[i].x,&a[i].a);
sort(a+1,a+n+1,cmp);
for(LL i=1;i<=n;i++)
for(LL j=60;j>=0;j--)
if((a[i].x>>j)&1)
{
if(!b[j]) {b[j]=a[i].x;ans+=a[i].a;break;}
else a[i].x^=b[j];
}
printf("%lld",ans);
}