CF1100F Ivan and Burgers(离线可删除线性基)
CF1100F Ivan and Burgers
题意比较清晰
(远古时期写的题,现在才写题解)
就是区间线性基
先考虑离线,按照右端点排序
考虑线性基的过程,就是这一位有值就取上
那么计
p
o
s
[
i
]
pos[i]
pos[i]表示第
i
i
i位有值的最大的
l
l
l(
l
<
=
r
l<=r
l<=r)
然后像正常的线性基一样插入值
如果
p
o
s
[
i
]
pos[i]
pos[i]>=l就表示第
i
i
i位有值,可以取
然后干就完了
#include<bits/stdc++.h>
#define N 1000005
using namespace std;
struct Q{
int l, r, id;
}q[N];
int cmp(Q x, Q y){
return x.r < y.r;
}
int n, a[N], m, ha[N], p[N], ANS[N];
void xxj(int x, int id){
for(int i = 20; i >= 0; i --){
if(x & (1 << i)){
if(!p[i]){
p[i] = x;
ha[i] = id;
return;
}
if(ha[i] < id) swap(ha[i], id), swap(x, p[i]);
x ^= p[i];
}
}
}
int query(int l){
int ret = 0;
for(int i = 20; i >= 0; i --){
if((p[i] ^ ret) > ret && ha[i] >= l) ret ^= p[i];
}
return ret;
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
scanf("%d", &m);
for(int i = 1; i <= m; i ++) scanf("%d%d", &q[i].l, &q[i].r), q[i].id = i;
sort(q + 1, q + 1 + m, cmp);
int pos = 0;
for(int i = 1; i <= m; i ++){
while(pos + 1 <= q[i].r){
pos ++;
xxj(a[pos], pos);
}
ANS[q[i].id] = query(q[i].l);
}
for(int i = 1; i <= m; i ++) printf("%d\n", ANS[i]);
return 0;
}