bzoj3105 [cqoi2013]新Nim游戏

很明显,题目要你求在拿走最少的火柴棍的情况下,如何让剩下的火柴堆的亦或值不含0。

先贪心的拍一发序,在动态的维护一下线性基就可以了。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
inline int cmp(int a,int b){
	return a>b;
}
inline int read(){
	int x=0,f=1,ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-'){f=-1;}ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int n,a[105];
int b[105];
inline bool ok(int x){
	int i;
	for(i=30;i>=0;i--)
		if(b[i]&&((x>>i)&1))
			x^=b[i];
	if(x) return true;
	return false;
}
inline void add(int x){
	int i;
	for(i=30;i>=0;i--)
		if(!b[i]&&((x>>i)&1)){
			b[i]=x;
			return ;
		}
		else if(b[i]&&((x>>i)&1)) x^=b[i];
}
int main(){
	n=read();int i;
	long long ans=0;
	for(i=1;i<=n;i++) a[i]=read();
	sort(a+1,a+1+n,cmp);
	for(i=1;i<=n;i++)
		if(ok(a[i])) add(a[i]);
		else ans+=a[i];
	cout<<ans<<endl;
	return 0;
}

  

posted @ 2017-02-27 21:50  古城独钓  阅读(111)  评论(0编辑  收藏  举报