前缀线性基(查询区间内异或最大值)
struct PrefixLinearBasis{
int d[maxn][32];//前缀线性基
int pos[maxn][32];//最后一个修改i这个位置的数
int cnt;
PrefixLinearBasis(){
memset(d,0,sizeof(d));
memset(pos,0,sizeof(pos));
cnt = 0;
}
void add(int x){//向线性基中添加x
cnt ++;
for(int i = 0; i < 32; i++){//复制前cnt-1个线性基
d[cnt][i] = d[cnt - 1][i];
pos[cnt][i] = pos[cnt - 1][i];
}
int P = cnt;
for(int i = 31; i >= 0; i--){
if((x >> i) & 1){
if(d[cnt][i]){//插入失败
if(pos[cnt][i] < P){//交换位置
swap(pos[cnt][i],P);
swap(d[cnt][i],x);
}
x ^= d[cnt][i];//异或
}
else{//插入成功
d[cnt][i] = x;
pos[cnt][i] = P;
break;
}
}
}
}
int queryMax(int l,int r){//查询[l,r]中的最大值
int res = 0;
for (int i = 31; i >= 0; i--){
if(pos[r][i] < l)
continue;
if ((res ^ d[r][i]) > res)
res ^= d[r][i];
}
return res;
}
int queryMin(int l,int r) {//查询[l,r]中的最小值
for(int i = 0; i <= 60; i++){
if(pos[r][i] < l)
continue;
if(d[r][i])
return d[r][i];
}
return 0;
}
}PLB;
线性基(最小值、最大值、k大值、合并、插入)(未测试)
struct LinearBasis{
int p[32];
int cnt;
bool flag = false;
LinearBasis(){
memset(p,0,sizeof p);
cnt = 0;
}
void insert(int x){
if (x){
for(int i = 31;i >= 0;i --){
if (!(x >> i & 1)) continue;
if (!p[i]) {
p[i] = x;
cnt ++;
return;
}
else x ^= p[i];
}
}
flag = true;
}
void rebuild(){
for(int i = 31;i >= 0;i --){
for(int j = i - 1;j >= 0;j --){
if (p[i] >> j & 1) p[i] ^= p[j];
}
}
}
long long query_kth(int x){
if (x >= (1ll << cnt)) return -1;
long long ans = 0;
for(int i = 60;i >= 0;i --){
if (x >> i & 1) ans ^= p[i];
}
return ans;
}
long long query_max(){
long long ans = 0;
for(int i = 31;i >= 0;i --){
if ((ans ^ p[i]) > ans) ans ^= p[i];
}
return ans;
}
long long query_min(){
if (!flag) return 0;
for(int i = 0;i <= 31;i ++){
if (p[i]) return p[i];
}
}
};
LinearBasis merge(LinearBasis a,LinearBasis b){
for(int i = 31;i >= 0;i --){
if (b.p[i]) a.insert(b.p[i]);
}
return a;
}