2017icpc Xi'an A.XOR
Meaning of the questions:
Length \ (n-\) array, \ (Q \) times query, query given every \ (L, R & lt \) , from \ ([l, r] \ ) is selected such that the number of digital numbers interval XOR and or \ (k \) maximum.
Ideas:
Random process group is a linear XOR problem, the maximum for this interval may be considered exclusive or combined with maintenance of the linear segment tree group.
Consider how we can have \ (k | (a_ {i_1 } \ xor \ a_ {i_2} \ xor \, ..., \ xor \ a_ {i_m}) \) maximum.
The idea is that the beginning: to come up with a linear range of the base, and then bit by bit from a high level of search, if \ (k \) have \ (1 \) , it does not consider this a linear group, if there is no \ (1 \) , we will certainly consider, but soon to include a counter-example.
Consider \ (k \) what it takes?
When \ (k \) This one has \ (1 \) , we can try to take care of him if this one does not \ (1 \) , we try to choose from to fill in the numbers, even if it is not.
So the \ (K \) negated, for each segment tree node into \ (K \ & A (I) \) , each query asking \ ([l, r] \ ) maximum result, the final result or the most \ (k \) .
Correctness:
When the pair \ (k \) after negated, for \ (a (i) \) with the operation, in fact, looking for \ (a (i) \) This bit has no \ (1 \) .
It is also likely to have been \ (a (i) \) have \ (1 \) place to take the anti \ (k \) get rid of, this need not worry, because the final answers or \ (k \) , on the back.
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4+10;
int n, m, k, a[maxn];
int l, r, ans;
struct LineBase
{
int p[32];
void init() {memset(p, 0, sizeof p);}
void ins(int x)
{
for(int i = 30; i >= 0; i--)
{
if(x&(1<<i))
{
if(!p[i])
{
p[i] = x;
return;
}
x ^= p[i];
}
}
}
int qmax()
{
int res = 0;
for(int i = 30; i >= 0; i--)
res = max(res, res^p[i]);
return res;
}
};
struct SegmentTree
{
int l, r;
LineBase t;
#define lson (p<<1)
#define rson (p<<1|1)
#define l(x) tree[x].l
#define r(x) tree[x].r
#define t(x) tree[x].t
}tree[maxn<<2];
LineBase merge_base(LineBase a, LineBase b)
{
for(int i = 30; i >= 0; i--)
if(a.p[i]) b.ins(a.p[i]);
return b;
}
void build(int p, int l, int r)
{
l(p) = l, r(p) = r;
t(p).init();
if(l == r)
{
t(p).ins(a[l]);
return;
}
int mid = (l+r)>>1;
build(lson, l, mid);
build(rson, mid+1, r);
t(p) = merge_base(t(lson), t(rson));
}
LineBase ask(int p, int l, int r)
{
if(l <= l(p) && r(p) <= r) return t(p);
int mid = (l(p)+r(p))>>1;
if(mid >= r) return ask(lson, l, r);
else if(mid < l) return ask(rson, l, r);
else return merge_base(ask(lson, l, r), ask(rson, l, r));
}
void solve()
{
scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
a[i] = a[i]&(~k);
}
build(1, 1, n);
while(m--)
{
scanf("%d%d", &l, &r);
LineBase tmp = ask(1, l, r);
ans = tmp.qmax();
ans = ans|k;
printf("%d\n", ans);
}
}
int main()
{
int T; scanf("%d", &T);
while(T--) solve();
return 0;
}