CodeForces - 1101G

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011528035/article/details/86636796

题意:洛谷有中文题意,链接:https://www.luogu.org/problemnew/show/CF1101G

思路:其实考虑到子集之间异或最多能够产生的数的数目其实是2^32,而且就是只需要32个数就可以了,所以答案小于32。而转换为二进制以后长度也就32。将其转换位多元一次方程组之后,发现如果子集之间是线性无关的话,必然是满足要求,而矩阵不管怎么变换,秩是不会变的,而且秩也小于32,所以也就考虑到了矩阵的秩,试了一下就过了。

本题大部分思路过程还是靠直觉,部分证明不太严谨,特别是推了几个线性相关的式子,发现都会出现0,就直接下手了

#include <stdio.h>
#include <algorithm>
using namespace std;

#define MAX 200010

int a[40][MAX];

int main()
{
    int n,x;
    scanf("%d",&n);
    int ans=0;
    for(int i=0;i<n;i++){
        scanf("%d",&x);
        ans=ans^x;
        for(int j=0;j<32;j++){
            if((1<<j)&x)
                a[j][i]=1;
        }
    }
    if(ans){
        ans=0;
        for(int k = 0,col=0;k < 32 && col < n;k++,col++)
        {
            int max_r=k;
            for(int i=k;i<32;i++)
            {
                if(a[i][col]){
                    max_r=i;
                    break;
                }
            }
            if(max_r!=k)
            {
                for(int j=col;j<n;j++)
                    swap(a[k][j],a[max_r][j]);
            }
            if(a[k][col]==0)
            {
                k--;
                continue;
            }
            ans++;
            for(int i=k+1;i<32;i++)
            {
                if(a[i][col]!=0)
                {
                    for(int j=col;j<n;j++)
                    {
                        a[i][j] = a[i][j]^a[k][j];
                    }
                }
            }
        }
        printf("%d\n",ans);
    }
    else
        printf("-1\n");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u011528035/article/details/86636796