线性基的目的是将数据压缩,通俗点,给你一组数组
现在你要把所有数组化成二进制,你压缩得到的最终数组必须保证两两数不交叉
交叉的定义就是如:
12
=
2
3
+
2
2
,
8
=
2
3
12=2^3+2^2,8=2^3
12=23+22,8=23,这两个数字在第三位交叉,还需要进行压缩
具体压缩方法:看是谁先进来占住了3这位,另一个数字必须与其异或,继续找下一位
注意:线性基必须从高位开始压,一开始图方便用lowerbit结果就很糟糕!!!
个人觉得线性基比较偏板子,如果出题必定会综合其它题型,比如最近杭电多校第一场把线性基和高斯消元结合,一般的板子会给你异或极大极小求法,或者异或值是否存在,
类似区间异或极大极小你去用暴力解肯定不现实。做了个板子
struct Linear_Base{
typedef int datatype;
const static int datasize=8*sizeof datatype;
datatype d[datasize];
bool flag;
Linear_Base(){memset(d,0,sizeof d);flag=false;}
void insert(datatype x){
for(int i=datasize-1;~i;i--){
if(x&(1ll<<i)){
if(!d[i]){
d[i]=x;
break;
}
else x^=d[i];
}
}
flag=true;
}
datatype query_max(datatype x=0){
for(int i=datasize-1;~i;i--){
x=max(x,x^d[i]);
}
return x;
}
bool check(datatype x){
for(int i=datasize-1;~i&&x;i--){
if(x&(1ll<<i)){
if(d[i]){
x^=d[i];
}
else return false;
}
}
return true;
}
datatype query_min(){
if(flag)return 0;
for(int i=0;i<datasize;i++)if(d[i])return d[i];
return 0;
}
};