Time:2016.09.07
Author:xiaoyimi
转载注明出处谢谢
传送门
思路:
水题
有一个比较明显的性质
如果一个数x不能添加到已选集合中,那么有且只有一个已选集合中的子集A,使得A xor x=0
因为如果至少有两个子集的话,那么另一个子集的异或和显然等于A的异或和,那么这个已选集合是不合法的
这样我们只要去掉A中的一个数就可以使x加入已选集合了
维护集合中最小值?
你咋不上天呢
考虑贪心
按照权值大小排序,然后往线性基里加就可以了
#include<cstdio>
#include<algorithm>
#define LL long long
using namespace std;
int n,ans;
LL lb[61];
struct node{
int data;
LL num;
}a[1001];
bool cmp(node a,node b){return a.data>b.data;}
main()
{
scanf("%d",&n);
for (int i=1;i<=n;++i) scanf("%lld%d",&a[i].num,&a[i].data);
sort(a+1,a+n+1,cmp);
for (int i=1;i<=n;++i)
for (int j=60;j>=0;--j)
if (a[i].num>>j&1)
if (!lb[j])
{lb[j]=a[i].num;ans+=a[i].data;break;}
else
a[i].num^=lb[j];
printf("%d",ans);
}