operation
The meaning of problems: the given length n and m number of columns operating times, each time at the end of a number or the number of columns is added to the sub-query interval R L set the maximum and XOR, by force. \ (n, m \ leq 5 \ times 10 ^ {5} \)
Solution: for all \ (i \ epsilon (1, n) \) maintains a \ ((1, i) \ ) linear group \ (A [I] [32] \) , and the idea is similar to a prefix, and for each linear yl every record what it was last inserted location \ (POS [I] [32] \) (linear group insert function thus necessary to slightly change it), so that the query \ ((L, R ) \) time interval only \ (a [R] \) of greater than or equal pos \ (L \) bit will \ ((L, R) \ ) interval contribute.
PS If there is no mandatory online then press the right endpoint of the interval only needs to maintain a linear ordering based on it.
PSS melon God taught me a prefix linear base orz
Code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5;
int n, m;
struct node{
int p[32], pos[32];
}a[maxn];
void ins(int x) {
n++;
a[n] = a[n - 1];
int pos = n;
for(int i = 31; i >= 0; i--) {
if(x & (1 << i)) {
if(!a[n].p[i]) {
a[n].p[i] = x;
a[n].pos[i] = pos;
return;
}
if(a[n].pos[i] < pos) {
swap(a[n].pos[i], pos);
swap(a[n].p[i], x);
}
x ^= a[n].p[i];
}
}
}
int qmax(int l, int r) {
int res = 0;
for(int i = 31; i >= 0; i--) {
if(a[r].pos[i] < l) continue;
if((a[r].p[i] ^ res)> res) res ^= a[r].p[i];
}
return res;
}
int main() {
int T;
cin >> T;
memset(a[0].p, 0, sizeof(a[0].p));
memset(a[0].pos, 0, sizeof(a[0].pos));
while(T--) {
scanf("%d%d", &n, &m);
int tmp = n;
n = 0;
for(int i = 1; i <= tmp; i++) {
int x;
scanf("%d", &x);
ins(x);
}
int las = 0;
while(m--) {
int f;
scanf("%d", &f);
if(f) {
int x;
scanf("%d", &x);
x ^= las;
ins(x);
}
else{
int l, r;
scanf("%d%d", &l, &r);
l = (l ^ las) % n + 1;
r = (r ^ las) % n + 1;
if(l > r) swap(l, r);
//cout << l << " " << r << '\n';
las = qmax(l, r);
printf("%d\n", las);
}
}
}
return 0;
}