从大到小加入线性基..我不会证明啊..还有拟阵是什么真心不想看啊好麻烦
大概就是判断一下如果当前这个数不能被已经有的数经过异或得到那么就不会有子集的异或和为0,就可以将当前的加入。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
long long ans;
long long ins[70];
struct node
{
long long x,y;
};
node a[1005];
inline long long read()
{
long long a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline bool operator<(node a,node b)
{
return a.y>b.y;
}
int main()
{
n=read();
for (int i=1;i<=n;i++)
a[i].x=read(),a[i].y=read();
sort(a+1,a+n+1);
for (int i=1;i<=n;i++)
{
for (int j=63;~j;j--)
if ((a[i].x>>j)&1)
{
if (!ins[j])
{
ins[j]=a[i].x;
break;
}
else a[i].x^=ins[j];
}
if (a[i].x) ans+=a[i].y;
}
cout << ans << endl;
return 0;
}