线性基的话,我觉得就是把n个数的排列简化成63个数,使其异或出来的数跟原来可以异或出来的数一样
先把矿石按权值从大到小排序
一个一个往里加
如果加进去的不合法,就放弃它,因为如果选了它,那么比它权值大的矿石就要放弃
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; const int N=1006; struct JI { ll order; ll val; bool friend operator < (JI a,JI b) { return a.val>b.val; } }ji[N]; ll n; ll p[68]; ll work() { ll ans=0; sort(ji+1,ji+1+n); for(int i=1;i<=n;++i) { for(int j=62;j>=0;--j) if( (((ll)1<<j)&ji[i].order) ) { if(!p[j]) { p[j]=ji[i].order; break; } ji[i].order^=p[j]; } if(ji[i].order) ans+=ji[i].val; } return ans; } int main(){ //freopen("in.in","r",stdin); scanf("%lld",&n); for(int i=1;i<=n;++i) scanf("%lld%lld",&ji[i].order,&ji[i].val); cout<<work(); }
原文:http://www.cnblogs.com/A-LEAF/p/7662244.html