【题意】
给定n个矿石,有价值和编号,求一个选择的矿石集合,使其中不存在一个子集的异或和为0,求这个集合的价值最大
【分析】
我们可以贪心的考虑, 如果当前存在x^y^z=0,那么意味着我们肯定要舍去一个,一定会舍去价值最小的那个
所以我们可以按照价值排序,加入线性基,直到无法加入为止
【代码】
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1005; int n; ll a[maxn],p[maxn],ans; struct point { ll num,val; }e[maxn]; bool cmp(point a,point b) { return a.val>b.val; } int main() { // freopen("a.in","r",stdin); // freopen("a.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld%lld",&e[i].num,&e[i].val); sort(e+1,e+n+1,cmp); for(int i=1;i<=n;i++) for(int j=63;j>=0;j--) { if(!(e[i].num&(1LL<<j))) continue; if(p[j]) e[i].num^=p[j]; else { p[j]=e[i].num; ans+=e[i].val; break; } } printf("%lld",ans); return 0; }