[BZOJ2460][BeiJing2011]元素

bzoj

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;
}
posted @ 2018-03-16 19:56  租酥雨  阅读(129)  评论(0编辑  收藏  举报