SGU_275
这个题目可以将每个数分解成64位来看待,于是我们可以从高位向低位扫描,尽可能让当前这位为1,而判断当前这位是否可能为1可以借助高斯消元。
#include<stdio.h> #include<string.h> #include<algorithm> #define MAXN 110 #define MAXM 70 using namespace std; long long a[MAXN]; int N, mat[MAXM][MAXN], code[MAXM][MAXN], ans[MAXM]; void decode(int i) { int j; long long x = a[i]; for(j = 63; j >= 0; j --) code[j][i] = x & 1, x >>= 1; } void init() { int i; for(i = 0; i < N; i ++) { scanf("%I64d", &a[i]); decode(i); } } int gauss(int n) { int i, j, k, x, y; for(i = j = 0; i <= n && j < N; i ++, j ++) { if(mat[i][j] == 0) { for(x = i + 1; x <= n; x ++) if(mat[x][j]) { for(y = j; y <= N; y ++) swap(mat[i][y], mat[x][y]); break; } if(x > n) { -- i; continue ; } } for(x = i + 1; x <= n; x ++) if(mat[x][j]) { for(y = j; y <= N; y ++) mat[x][y] ^= mat[i][y]; } } for(k = i; k <= n; k ++) if(mat[k][N]) return 0; return 1; } void solve() { int i, j, k; long long res = 0; for(i = 0; i < 64; i ++) { ans[i] = 1; for(j = 0; j <= i; j ++) { for(k = 0; k < N; k ++) mat[j][k] = code[j][k]; mat[j][N] = ans[j]; } if(!gauss(i)) ans[i] = 0; } for(i = 0; i < 64; i ++) res = (res << 1) | ans[i]; printf("%I64d\n", res); } int main() { while(scanf("%d", &N) == 1) { init(); solve(); } return 0; }