BZOJ 2460 元素 线性基+贪心

来源:互联网 发布:淘宝类目在哪里设置 编辑:程序博客网 时间:2024/06/03 03:39

线性基是一种特殊的基,它通常会在异或运算中出现,它的意义是:通过原集合S的某一个最小子集S1使得S1内元素相互异或得到的值域与原集合S相互异或得到的值域相同。

性质:

线性基能相互异或得到原集合的所有相互异或得到的值。

线性基是满足性质1的最小的集合

线性基没有异或和为0的子集。



题意:n个矿石,第i个矿石有编号num[i]和价值val[i] num[i]<=1e18,val[i]<=1e4,n<=1e3.
问从n个中选出若干个矿石,在这些矿石编号num[i]异或和不为0的情况下,其价值和最大为多少

选出子集的异或和不为0 马上想到线性基,然后贪心将val从大到小排序后,构造线性基即可.

#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N=2e5+20;const ll inf=2e16;struct node{ll num,val;}a[N];bool cmp(node a,node b){return a.val>b.val;}ll mk[110];int main(){int n;scanf("%d",&n);for(int i=1;i<=n;i++)cin>>a[i].num>>a[i].val;sort(a+1,a+1+n,cmp);memset(mk,0,sizeof(mk));ll ans=0;for(int i=1;i<=n;i++){ll x=a[i].num;for(ll j=63;j>=0;j--){if(((x>>j)&1)==0)continue;if(!mk[j]){mk[j]=x;break;}x^=mk[j];//Èô×îºóx==0 Ôò˵Ã÷x¿ÉÒÔͨ¹ýÆäËûÊýÒì»ò³öÀ´. }if(x)ans+=a[i].val;}cout<<ans<<endl;return 0;} 


原创粉丝点击