Whenever we come across range queries, prefix sums should immediately come to
mind. However, since we are dealing with XOR sums over a range, we have to use a
prefix XOR array rather than a prefix sum array. To do so, we can define
prefix as an array such that
prefix[i]=arr[0]⊕arr[1]⊕⋯⊕arr[i].
Thus, for each query (a,b), our answer is simply
prefix[a−1]⊕prefix[b].
Proof
We know that
prefix[a−1]=arr[0]⊕arr[1]⊕⋯⊕arr[a−1].
We also know that
prefix[b]=arr[0]⊕arr[1]⊕⋯⊕arr[b].
Therefore, since x⊕x=0 for any x:
prefix[a−1]⊕prefix[b]=cancels out to 0arr[0]⊕arr[0]⊕arr[1]⊕arr[1]⊕⋯⊕arr[a−1]⊕arr[a−1]⊕arr[a]⊕arr[a+1]⋯⊕arr[b].
This simplifies to
arr[a]⊕arr[a+1]⋯⊕arr[b], which
is exactly what we're looking for.
Implementation
Time Complexity:O(N+Q)
n, q =map(int,input().split())
arr =list(map(int,input().split()))
xor_arr =[0]*(n +1)
for i inrange(1, n +1):
xor_arr[i]= arr[i -1]^ xor_arr[i -1]
for _ inrange(q):
a, b =map(int,input().split())
print(xor_arr[b]^ xor_arr[a -1])
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!