题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2460
解法:从大到小排序,依次贪心的添加到当前集合就可以了,需要动态维护线性基。用拟阵证明,线性基性质,线性基中任意子集异或和不为0,所以从大到小加入就好。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
struct node{
LL a, b;
node(){}
bool operator<(const node &rhs) const{
return b>rhs.b;
}
}a[1005];
int n;
LL bin[65];
LL p[65];
int main()
{
bin[0] = 1;
for(int i=1; i<=63; i++) bin[i] = bin[i-1]<<1;
scanf("%d", &n);
for(int i=1; i<=n; i++){
scanf("%lld %lld", &a[i].a, &a[i].b);
}
LL ans = 0;
sort(a+1, a+n+1);
for(int i=1; i<=n; i++){
for(int j=63; j>=0; j--){
if(a[i].a&bin[j]){
if(!p[j]){
p[j] = i;
break;
}
else{
a[i].a ^= a[p[j]].a;
}
}
}
if(a[i].a) ans += a[i].b;
}
printf("%lld\n", ans);
return 0;
}