记录编号 |
140098 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[CQOI2013]新Nim游戏 |
最终得分 |
100 |
用户昵称 |
cstdio |
是否通过 |
通过 |
代码语言 |
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;
}