题意:给n个数(n<=100),每个数在long long 范围内,任意选一些数异或起来,问异或值最大为多少
分析:高斯消元。
a[i][j]:第j个数的第i位。尽量让每一位都为1,这样是最大的。所以让a[i][n]=1;
然后解方程…
其中感觉还有点想不明白
先把代码贴在这里,然后看到异或线性基的时候再来填
//wa 21,是因为不能直接1<<60这样会爆的.可以和下面一样用一个数组,或者加ll
using namespace std;
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn = 110;
int a[maxn][maxn];
ll bit[maxn];
int main()
{
int n;ll t;
bit[0] = 1;
for(int i = 1;i < 63;i++)
bit[i] = 2*bit[i-1];
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;i++)
{
cin>>t;
for(int j=0;j<=60;j++)
{
a[j][i]=(t>>(60-j))&1;
}
}
for(int i=0;i<=60;i++) a[i][n]=1;
ll ans=0;
for(int i=0;i<=60;i++)
{
int x=-1;
for(int j=0;j<n;j++)
{
if(a[i][j])
{
x=j;break;
}
}
if(x==-1&&!a[i][n])
{
ans=ans+bit[60-i];
}
else if(x!=-1){
ans=ans+bit[60-i];
for(int k = i+1;k <= 60;k++)
{
if(a[k][x])
{
for(int c=x;c<=n;c++)
a[k][c]^=a[i][c];
}
}
}
}
cout<<ans<<endl;
}
return 0;
}
/*
3
11 9 5
*/