题目描述:
就是给你n个数然后从中选择一些出来异或,求异或可得到的最大值
解题思路:
跟据题目可以假设答案ans=d1d2d3d4...(di代表ans的二进制位0/1)(这里不是乘法哦),从高位一直枚举到低位,检验是否可行。但如果直接检验的话,复杂度是O(2^n),显然超时。所以可以从高位枚举到低位,同时枚举检验每一位的可行性。我们可以根据这个列出方程组,这样检验可行性就成了检查截至当前的方程组是否有解。

引入:异或方程组解法(本题仅用到了判定有解,因此只要消元就行)
很多异或问题都要涉及到解异或方程组,因此首先要搞懂异或方程组的解法。
异或方程组的格式(设有n个未知数,m个方程):
a11x1 XOR a12x2 XOR ... XOR a1nxn = b1
a21
x1 XOR a22x2 XOR ... XOR a2nxn = b2
……………………………………………………
am1x1 XOR am2x2 XOR ... XOR amn*xn = bm

第一阶段(消元):设置一个变量p,一开始p=1,然后,i从1到n,每次执行:<1>若在第p个及以后的方程中,至少有一个方程的xi系数为1,设为第q个方程,则先将第p、q个方程交换,然后用第p个方程去XOR后面剩下的所有xi系数为1的方程(各系数包括b都对应进行XOR运算,实际上就是矩阵初等行变换),将它们的xi系数均变成0,最后p加1;<2>否则(第p个及以后的方程中xi系数均为0),回到p-1行,col++;
最后结束的时候已经化成了阶梯型,就可以判别方程组有解还是无解。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[60];
ll Bits[60];
int T[60][60];
int Ma[60][60];
bool check(int n, int m, int k)
{
    int row,col;
    for(row = col = 1; row <= k && col <= n; row++, col++)
    {
        if(!Ma[row][col])
        for(int i = row+1; i <= k; i++) {
            if(Ma[i][col]) {
                swap(Ma[i], Ma[row]);    //交换两行
                break;
            }
        }
        if(!Ma[row][col]) {
            row--;
            continue;
        }
        for(int i = row+1; i <= k; i++) {
            if(Ma[i][col]) {
                for(int j = col; j <= m; j++) {
                    Ma[i][j] ^= Ma[row][j];
                }
            }
        }
    }
    for(int i = row; i <= k; i++) {
        if(Ma[i][m]) return false;
    }
    return true;
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i = 1; i <= n; i++) {
        scanf("%lld",&a[i]);
    }
    Bits[1] = 1;
    memset(T, 0, sizeof(T));
    for(int i = 2; i <= 51; i++) {
        Bits[i] = Bits[i-1] << 1;
    }
    for(int i = 51; i >= 1; i--) {
        T[i][n+1] = 1;
        for(int j = 1; j <= n; j++) {
            if((Bits[i] & a[j]) > 0) {
                T[i][j] = 1;
            }
        }
        memcpy(Ma, T, sizeof(Ma));
        if(!check(n, n+1, 51))
            T[i][n+1] = 0;
    }
    long long ans = 0;
    for(int i=1;i<=51;i++)
        ans += 1LL * T[i][n+1] * Bits[i];
    printf("%lld\n", ans);
}