版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}