Link \rule{20pt}{15pt}\kern{-16.5pt}\color{white}\raisebox{4.7pt}{\footnotesize\sf Link} Link
单点修改,区间查询,可以想到线段树。
然后在线段树的每一个节点上套一个线性基维护即可。
记得:线性基查询/合并一定要从大到小遍历。
//P4839 need O2
#include <bits/stdc++.h>
using namespace std;
const int N = 5e4 + 10;
inline int read(){
int x = 0; char ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
return x;
}
struct basis{
int p[32];
void ins(int val){
for(int i = 31; i >= 0; -- i){
if(!(val&(1<<i))) continue;
if(!p[i]){ p[i] = val; break; }
val ^= p[i];
}
}
void ins(basis &x){
for(int i = 31; i >= 0; -- i)
ins(x.p[i]);
}
} T[N<<2], res;
int n, m;
int calc(basis x){
int ans = 0;
for(int i = 31; i >= 0; -- i)
ans = max(ans, ans^x.p[i]);
return ans;
}
void modify(int p, int L, int R, int pos, int val){
if(L == R) T[p].ins(val);
else {
int mid = L + R >> 1;
if(pos <= mid) modify(p<<1, L, mid, pos, val);
else modify(p<<1|1, mid+1, R, pos, val);
T[p].ins(T[p<<1]), T[p].ins(T[p<<1|1]);
}
}
void query(int p, int L, int R, int l, int r){
if(l <= L && R <= r) res.ins(T[p]);
else {
int mid = L + R >> 1;
if(l <= mid) query(p<<1, L, mid, l, r);
if(mid < r) query(p<<1|1, mid+1, R, l, r);
}
}
signed main(){
n = read(); m = read();
for(int i = 1, op, a, b; i <= n; ++ i){
op = read(); a = read(); b = read();
if(op == 1) modify(1, 1, m, a, b);
else{
for(int j = 0; j <= 31; ++ j) res.p[j] = 0;
query(1, 1, m, a, b);
printf("%d\n", calc(res));
}
}
return 0;
}
做完了这题可以去做 P5607 [Ynoi2013] 无力回天 NOI2017