线性基学习笔记

线性基是干嘛的呢?

给定n个数,求所有数的异或和最大是多少?

求解这类问题的时候,就需要线性基了

个人感觉线性基本身就一种贪心。

首先定义(base[i])表示最高位1在i位的数是什么

对于新进来的数(tmp),我们先找出他最高位上的1,假设为第(j)位,然后看一下(base[j])有没有数,如果没有,直接将它赋值成(tmp),如果有,那就(tmp^=base[j])就有点像高斯消元 对,把(tmp)这位的1消去(或者说,这个数去掉这位1之后,还能对哪些(base)作贡献),那么我们考虑,经过这个处理,(tmp)要么被加入了base,要么变成了0(就是他可以被之前的数异或得到)

(max)的时候,我们就贪心即可

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long

using namespace std;

inline ll read()
{
  ll x=0,f=1;char ch=getchar();
  while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
  while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  return x*f;
}

ll n,tmp;
ll base[110];
int main()
{
  n=read();
  for (int i=1;i<=n;i++){
  	tmp=read();
  	for (int j=63;j>=0;j--)
  	{
  		if (tmp & (1LL << j))
  		{
  			if (!base[j]) 
			  {
			    base[j]=tmp;
			    break;
			  }
  			tmp^=base[j];
		  }
	  }
  }
  ll ans=0;
  for (int i=63;i>=0;i--)
  {
  	 if (ans<(ans ^ base[i])) ans^=base[i];
  }
  cout<<ans;
  return 0;
}

这里补充一个线性基的性质

1>同时线性基的任何一个非空子集都不会使得其(xor)和为0

2>果有很多个数,我们可以构出这些数的线性基,那么这个线性基可以通过互相xor,能够构出原来的数可以相互xor构出的所有的数。就可以减少判断的时间和次数。

原文地址:https://www.cnblogs.com/yimmortal/p/10160826.html