CSES - Range Xor Queries

Authors: Danh Ta Chi Thanh, Nathan Gong

Explanation

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\texttt{prefix} as an array such that prefix[i]=arr[0]arr[1]arr[i]\texttt{prefix}[i]= \texttt{arr}[0] \oplus \texttt{arr}[1] \oplus \dots \oplus \texttt{arr}[i]. Thus, for each query (a,b)(a, b), our answer is simply prefix[a1]prefix[b]\texttt{prefix}[a-1]\oplus \texttt{prefix}[b].

Proof

We know that prefix[a1]=arr[0]arr[1]arr[a1]\texttt{prefix}[a-1]= \texttt{arr}[0] \oplus \texttt{arr}[1] \oplus \dots \oplus \texttt{arr}[a-1]. We also know that prefix[b]=arr[0]arr[1]arr[b]\texttt{prefix}[b]= \texttt{arr}[0] \oplus \texttt{arr}[1] \oplus \dots \oplus \texttt{arr}[b].

Therefore, since xx=0x\oplus x = 0 for any xx:

prefix[a1]prefix[b]=arr[0]arr[0]arr[1]arr[1]arr[a1]arr[a1]cancels out to 0arr[a]arr[a+1]arr[b]\texttt{prefix}[a-1] \oplus \texttt{prefix}[b]= \underbrace{\texttt{arr}[0] \oplus \texttt{arr}[0] \oplus \texttt{arr}[1] \oplus \texttt{arr}[1] \oplus \dots \oplus \texttt{arr}[a-1] \oplus \texttt{arr}[a-1]}_{\text{cancels out to 0}} \oplus \texttt{arr}[a] \oplus \texttt{arr}[a+1] \dots \oplus \texttt{arr}[b].

This simplifies to arr[a]arr[a+1]arr[b]\texttt{arr}[a] \oplus \texttt{arr}[a+1] \dots \oplus \texttt{arr}[b], which is exactly what we're looking for.

Implementation

Time Complexity: O(n+q)\mathcal{O}(n+q)

Implementation Note:

The operator for XOR in C++, Java, and Python is ^.

C++

#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 2e5;
int n, q, arr[MAX_N + 1], prefix[MAX_N + 1], a, b;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);

Java

import java.io.*;
import java.util.*;
public class RangeXorQueries {
public static void main(String[] args) {
Kattio io = new Kattio();
int n = io.nextInt();
int q = io.nextInt();
// arr and prefix use 1-based indexing

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!