给出 q ≤ 5 e 4 q\leq5e4 q≤5e4个操作,在 k k k位置插入一个 x x x的数或者查询区间异或和最大为多少。同样是每个结点维护区间的线性基,线段树暴力合并。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll INF=LONG_LONG_MAX;
const int N=5e4+7;
int b[N<<2][31];
int ans[31];
void add(int b[],int x) {
for(int i=30;i>=0;i--) {
if(x&(1<<i)) {
if(!b[i]) {
b[i]=x;
break;
}
else x^=b[i];
}
}
}
void pushup(int rt) {
for(int i=30;i>=0;i--)
b[rt][i]=b[rt<<1][i];
for(int i=30;i>=0;i--)
add(b[rt],b[rt<<1|1][i]);
}
void modify(int rt,int l,int r,int k,int x) {
if(l==r) {
add(b[rt],x);
return;
}
int mid=(l+r)>>1;
if(k<=mid) modify(rt<<1,l,mid,k,x);
else modify(rt<<1|1,mid+1,r,k,x);
pushup(rt);
}
void query(int rt,int l,int r,int L,int R) {
if(R<l||L>r) return;
if(L<=l&&r<=R) {
for(int i=30;i>=0;i--) {
add(ans,b[rt][i]);
}
return;
}
int mid=(l+r)>>1;
query(rt<<1,l,mid,L,R);
query(rt<<1|1,mid+1,r,L,R);
}
int main() {
int q,n;
scanf("%d%d",&q,&n);
while(q--) {
int opt,l,r,k,x;
scanf("%d",&opt);
if(opt==1) {
scanf("%d%d",&k,&x);
modify(1,1,n,k,x);
}
if(opt==2) {
scanf("%d%d",&l,&r);
for(int i=30;i>=0;i--)
ans[i]=0;
query(1,1,n,l,r);
int res=0;
for(int i=30;i>=0;i--) {
if((res^ans[i])>res) {
res^=ans[i];
}
}
printf("%d\n",res);
}
}
return 0;
}