线性基
介绍:
理解起来挺简单的一个东西
基于xor产生的东西
线性基实际上是一个集合
这个集合xor能得到的值和原集合相同
构造方法:
我们用f[i]记录最高位1在第i位的数
插入一个新元素时,我们从最高位开始扫描
如果f[i]是空的,那么f[i]=x
否则x^=f[i]
1.求xor最大值
这个只要贪心就可以了,如果加入这个有优势就加进来
2.求xor最小值
就是线性基中的最小值
3.求xor k小值
前两个都是很显然的,这个还是有一定难度的
我们会发现 对于每个线性基 我们有选和不选两种状态 将其看成一个二进制
能把它看成二进制的令一个重要因素在于,后面的位的影响比前面要小
例如二进制中2^1<2^2<2^3...... 这里同样
那么我们要求k小值
也就是二进制的k小
所以每个数取不取就看k这一位是否为1就可以了
模板代码:
位运算多打括号
#include <bits/stdc++.h> using namespace std; #define ll long long #define N 200 ll a[N],f[N],n; int main() { freopen("noi.in","r",stdin); freopen("noi.out","w",stdout); cin>>n; for (ll i=1;i<=n;i++) cin>>a[i]; for (ll k=1;k<=n;k++) { ll x=a[k]; for (ll i=60;i;i--) if ((x>>(i-1))&1) { if (f[i]) x^=f[i]; else { f[i]=x; break; } } } ll ans=0; for (ll i=60;i>=1;i--) { if ((f[i]^ans)>ans) ans=f[i]^ans; //位运算多括号啊 比>优先级还低。。。 } cout<<ans; return 0; }