记录编号 140098 评测结果 AAAAAAAAAA
题目名称 [CQOI2013]新Nim游戏 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 0.011 s
提交时间 2014-11-19 10:00:12 内存使用 0.33 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
typedef long long LL;
const int SIZE=110,BTN=31;
bool Gauss_Jordan(bool A[SIZE][SIZE],int n,int m){//是否有解
	//行数0~n-1,列数0~m(m这一列是常数)
	for(int i=0;i<n&&i<m;i++){
		int p=i;
		for(int k=i+1;k<n;k++) if(A[k][i]>A[p][i]) p=k;
		if(!A[p][i]) continue;
		for(int k=0;k<=m;k++) swap(A[i][k],A[p][k]);
		for(int j=0;j<n;j++){
			if(j==i||!A[j][i]) continue;
			for(int k=0;k<=m;k++) A[j][k]^=A[i][k];
		}
	}
	//两种0=1的姿势
	for(int i=0;i<n&&i<m;i++)
		if(A[i][i]==0&&A[i][m]!=0) return false;
	for(int i=m;i<n;i++)
		if(A[i][m]!=0) return false;
	return true;
}
int N;
int A[SIZE]={0};
vector<int> stay;
bool G[SIZE][SIZE];
bool check(int x){
	if(stay.size()==0&&x) return false;//总之不可能表示
	memset(G,0,sizeof(G));
	int n=BTN,m=stay.size();
	for(int i=0;i<n;i++){//第i位
		for(int j=0;j<m;j++) G[i][j]=(stay[j]>>i)&1;
		G[i][m]=(x>>i)&1;
	}
	return Gauss_Jordan(G,n,m);
}
void work(void){
	sort(A+1,A+1+N);
	LL ans=0;
	for(int i=N;i>=1;i--){//从大到小试图留下
		if(check(A[i])) ans+=A[i];//可以被表示,不在线性无关的向量组中
		else stay.push_back(A[i]);
	}
	printf("%lld\n",ans);
}
void read(void){
	scanf("%d",&N);
	for(int i=1;i<=N;i++) scanf("%d",&A[i]);
}
int main(){
	freopen("newnim.in","r",stdin);
	freopen("newnim.out","w",stdout);
	read();
	work();
	return 0;
}