题解:
贪心+线性基。
先按贡献从小到大排序,然后对于每个矿石扔到线性基中查找。
找不到就加上贡献,推进线性基。
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int N = 1050; template<typename T> inline void read(T&x) { T f = 1,c = 0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();} x = f*c; } int n; struct Pair { ll x; int y; }p[N]; bool cmp(Pair a,Pair b){return a.y>b.y;} struct lb { ll c[70]; bool find(ll k) { for(int i=63;i>=0;i--)if(k&(1ll<<i)) { if(c[i])k^=c[i]; else return 1; } return k!=0; } void insert(ll k) { for(int i=63;i>=0;i--)if(k&(1ll<<i)) { if(c[i])k^=c[i]; else { c[i]=k; break; } } } }tr; int main() { read(n); for(int i=1;i<=n;i++) read(p[i].x),read(p[i].y); sort(p+1,p+1+n,cmp); ll ans = 0; for(int i=1;i<=n;i++) { if(tr.find(p[i].x)) { tr.insert(p[i].x); ans+=p[i].y; } } printf("%lld\n",ans); return 0; }