SGU-275 To xor or not to xor 高斯消元

  题目连接:http://acm.sgu.ru/problem.php?contest=0&problem=275

  题意:给n个数字,从中选取某些数字进行XOR操作,使得值最大。

  肯定要把每个数字转化为二进制的形式。在XOR操作的时候,首先优先高位,如果高位能取得 1 ,那么就一定要取 1 ,这其中肯定有很多情况,我们并不要求出每种情况去扩展,因为状态太多了,只要判断有没有满足的情况就可以了。这里就是异或高斯消元了。假设现在是判断第 i 位,那么首先把A[i][n]赋值为 1,如果在当前方程下有解,那么继续地位,否则把A[i][n]赋值为0,继续低位。

  1 //STATUS:C++_AC_15MS_943KB

  2 #include <functional>

  3 #include <algorithm>

  4 #include <iostream>

  5 //#include <ext/rope>

  6 #include <fstream>

  7 #include <sstream>

  8 #include <iomanip>

  9 #include <numeric>

 10 #include <cstring>

 11 #include <cassert>

 12 #include <cstdio>

 13 #include <string>

 14 #include <vector>

 15 #include <bitset>

 16 #include <queue>

 17 #include <stack>

 18 #include <cmath>

 19 #include <ctime>

 20 #include <list>

 21 #include <set>

 22 #include <map>

 23 using namespace std;

 24 //using namespace __gnu_cxx;

 25 //define

 26 #define pii pair<int,int>

 27 #define mem(a,b) memset(a,b,sizeof(a))

 28 #define lson l,mid,rt<<1

 29 #define rson mid+1,r,rt<<1|1

 30 #define PI acos(-1.0)

 31 //typedef

 32 typedef long long LL;

 33 typedef unsigned long long ULL;

 34 //const

 35 const int N=110;

 36 const int INF=0x3f3f3f3f;

 37 const int MOD=100000,STA=8000010;

 38 const LL LNF=1LL<<60;

 39 const double EPS=1e-8;

 40 const double OO=1e15;

 41 const int dx[4]={-1,0,1,0};

 42 const int dy[4]={0,1,0,-1};

 43 const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

 44 //Daily Use ...

 45 inline int sign(double x){return (x>EPS)-(x<-EPS);}

 46 template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}

 47 template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}

 48 template<class T> inline T lcm(T a,T b,T d){return a/d*b;}

 49 template<class T> inline T Min(T a,T b){return a<b?a:b;}

 50 template<class T> inline T Max(T a,T b){return a>b?a:b;}

 51 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}

 52 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}

 53 template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}

 54 template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}

 55 //End

 56 

 57 int A[N][N];

 58 LL num[N];

 59 int n;

 60 

 61 int gauss(int n,int m)

 62 {

 63     int i,j,k,cnt,row;

 64     for(i=row=0;i<n;i++){

 65         if(!A[row][i]){

 66             for(j=row+1;j<m;j++){

 67                 if(A[j][i]){

 68                     for(k=i;k<=n;k++)swap(A[row][k],A[j][k]);

 69                     break;

 70                 }

 71             }

 72         }

 73         if(A[row][i]!=1)continue;    //保证为严格的阶梯矩阵

 74         for(j=0;j<m;j++){    //从0开始,高斯约当消元

 75             if(j!=row && A[j][i]){

 76                 for(k=i;k<=n;k++)

 77                     A[j][k]^=A[row][k];

 78             }

 79         }

 80         row++;

 81     }

 82     for(i=m-1;i>=row;i--)

 83         if(A[i][n])return 0;   //无解

 84     return 1;

 85 }

 86 

 87 int main()

 88 {

 89  //   freopen("in.txt","r",stdin);

 90     int i,j;

 91     LL ans;

 92     while(~scanf("%d",&n))

 93     {

 94         for(i=0;i<n;i++)

 95             scanf("%I64d",&num[i]);

 96         ans=0;

 97         for(i=60;i>=0;i--){

 98             for(j=0;j<n;j++)

 99                 A[60-i][j]=(num[j]&((LL)1<<i))?1:0;

100             A[60-i][n]=1;

101             

102             if(gauss(n,60-i+1))ans|=(LL)1<<i;

103             else A[60-i][n]=0;

104         }

105 

106         printf("%I64d\n",ans);

107     }

108     return 0;

109 }

 

你可能感兴趣的:(or)