[BZOJ2460][BeiJing2011]元素
sol
按照魔力值排序,然后从大到小能放则放。
这个贪心是很显然的,因为如果几个数放在一起不合法,那么去掉这些数中的任意一个都可以使之合法。所以肯定去掉最小的那个。也就是从大到小能加入则加入。
加入时用线性基算一下异或最小值,为0就说明不能加入。
code
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
ll gi()
{
ll x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
const int N = 1005;
int n,ans;
struct mogician{
ll num;int mogic;
bool operator < (const mogician &b) const
{return mogic>b.mogic;}
}p[N];
struct xxj{
ll p[70];
void insert(ll x)
{
for (int j=63;j>=0;--j)
{
if (!(x>>j)) continue;
if (!p[j]) {p[j]=x;return;}
x^=p[j];
}
}
ll query(ll x)
{
for (int j=63;j>=0;--j)
x=min(x,x^p[j]);
return x;
}
}S;
int main()
{
n=gi();
for (int i=1;i<=n;++i) p[i].num=gi(),p[i].mogic=gi();
sort(p+1,p+n+1);
for (int i=1;i<=n;++i)
if (S.query(p[i].num))
ans+=p[i].mogic,S.insert(p[i].num);
printf("%d\n",ans);
return 0;
}