SGU 275 To xor or not to xor

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;

}

你可能感兴趣的:(or)