Given an array **arr[]** of size **n** and **q** queries and an integer **k**. Each query consists of an index range **[l, r]** and the task is to count the number of pairs of indices **i** and **j** such that **l ≤ i ≤ j ≤ r** (1-based indexing) and the xor of the elements **a[i], a[i + 1], …, a[j]** is equal to **k**.

**Examples:**

Input:arr[] = {1, 1, 1, 0, 2, 3}, q[] = {{2, 6}}, k = 3

Output:2

{1, 0, 2} and {3} are the required sub-arrays

within the index range [2, 6] (1-based indexing)

Input:arr[] = {1, 1, 1}, q[] = {{1, 3}, {1, 1}, {1, 2}}, k = 1

Output:

4

1

2

**Approach:** **This post** discusses to find sub-arrays with a given xor in O(n) per query, so if q is large, our total run time complexity would be O(n * q).

Since we are given queries offline, The idea is to use’s Mo’s algorithm. We divide the array into sqrt(n) blocks and sort the queries according to block index, ties are broken with less r value first.

We will keep an array xorr[], where xorr[i] stores the xor of the prefix of array elements from 0 to i (index 0 based).

We will also keep another array cnt[], where cnt[y] stores the number of prefixes with xorr[i] = k.

Suppose, we add an element at index x, let xorr[x] ^ k = y, now if cnt[y] is greater than 0 then there exists prefixes with same xor, so we get y sub-arrays with a given xor k that end at index x.

Below is the implementation of the above approach:

`// C++ implementation of the approach ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` `const` `long` `long` `bsz = 316; ` `long` `long` `res = 0; ` ` ` `// Query structure ` `struct` `Query { ` ` ` `long` `long` `l, r, q_idx, block_idx; ` ` ` ` ` `Query() {} ` ` ` `Query(` `long` `long` `_l, ` `long` `long` `_r, ` `long` `long` `_q_idx) ` ` ` `{ ` ` ` `l = _l, r = _r, q_idx = _q_idx, block_idx = _l / bsz; ` ` ` `} ` ` ` ` ` `// We use operator overloading ` ` ` `// to sort the queries ` ` ` `bool` `operator<(` `const` `Query& y) ` `const` ` ` `{ ` ` ` `if` `(block_idx != y.block_idx) ` ` ` `return` `block_idx < y.block_idx; ` ` ` `return` `r < y.r; ` ` ` `} ` `}; ` ` ` `Query queries[1000005]; ` `unordered_map<` `long` `long` `, ` `long` `long` `> cnt; ` `long` `long` `n, q, k; ` `long` `long` `xorr[1000005]; ` ` ` `// Function to add elements while traversing ` `void` `add(` `long` `long` `u) ` `{ ` ` ` `long` `long` `y = xorr[u] ^ k; ` ` ` ` ` `// We find the number of prefixes with value y ` ` ` `// that are contributing to the answer, ` ` ` `// add them to the answer ` ` ` `res = res + cnt[y]; ` ` ` ` ` `// If we are performing add operation, and suppose ` ` ` `// we are at index u then count of xorr[u] ` ` ` `// will increase by 1 as we are adding ` ` ` `// the answer to the list ` ` ` `cnt[xorr[u]]++; ` `} ` ` ` `// Function to delete elements while traversing ` `void` `del(` `long` `long` `u) ` `{ ` ` ` `// If we are performing delete operation and suppose ` ` ` `// we are at index u then count of xorr[u] ` ` ` `// will decrease by 1 as we are removing ` ` ` `// the answer from the list ` ` ` `cnt[xorr[u]]--; ` ` ` `long` `long` `y = xorr[u] ^ k; ` ` ` ` ` `// We find the number of prefixes with value y ` ` ` `// that was initially contributing to the answer ` ` ` `// now we do not need them, hence subtract it from answer ` ` ` `res = res - cnt[y]; ` `} ` ` ` `// Here we are performing Mo's algorithm ` `// if you have no idea of it then go through here: ` `// https:// www.geeksforgeeks.org/mos-algorithm-query-square-root-decomposition-set-1-introduction/ ` `void` `Mo() ` `{ ` ` ` `// first we sort the queries with block index, and ties are broken by less r value . ` ` ` `sort(queries + 1, queries + q + 1); ` ` ` `vector<` `long` `long` `> ans(q + 1); ` ` ` `long` `long` `l = 1, r = 0; ` ` ` `res = 0; ` ` ` `cnt[0] = 1; ` ` ` ` ` `// Iterate each query and check whether ` ` ` `// we have to move the left and right pointer ` ` ` `// to left or right ` ` ` `for` `(` `long` `long` `i = 1; i <= q; ++i) { ` ` ` ` ` `// If current right pointer r is less than ` ` ` `// the rightmost index of the present query, ` ` ` `// increment r ` ` ` `while` `(r < queries[i].r) { ` ` ` `++r; ` ` ` ` ` `// While incrementing we are adding new numbers ` ` ` `// to our list. Hence, we modify our answer ` ` ` `// for each r using add() function ` ` ` `add(r); ` ` ` `} ` ` ` ` ` `// If current left pointer is greater than the ` ` ` `// left most index of the present query, decrement l ` ` ` `while` `(l > queries[i].l) { ` ` ` `l--; ` ` ` ` ` `// While decrementing l, we are again adding ` ` ` `// new numbers to our list, hence we modify ` ` ` `// our answer using add() function ` ` ` `add(l - 1); ` ` ` `} ` ` ` ` ` `// Similarly, if current left pointer is less than ` ` ` `// the left most index of the present query, increment l ` ` ` `while` `(l < queries[i].l) { ` ` ` ` ` `// While incrementing we are deleting elements ` ` ` `// as we are moving right, hence we modify our answer ` ` ` `// using del() function ` ` ` `del(l - 1); ` ` ` `++l; ` ` ` `} ` ` ` ` ` `// If current right pointer is greater than the rightmost ` ` ` `// index of the present query, decrement it ` ` ` `while` `(r > queries[i].r) { ` ` ` ` ` `// While decrementing, modify the answer ` ` ` `del(r); ` ` ` `--r; ` ` ` `} ` ` ` `ans[queries[i].q_idx] = res; ` ` ` `} ` ` ` `for` `(` `long` `long` `i = 1; i <= q; ++i) { ` ` ` `cout << ans[i] << endl; ` ` ` `} ` `} ` ` ` `// Driver code ` `int` `main() ` `{ ` ` ` `q = 3, k = 3; ` ` ` `vector<` `long` `long` `> v; ` ` ` `v.push_back(0); ` ` ` `v.push_back(1); ` ` ` `v.push_back(1); ` ` ` `v.push_back(1); ` ` ` `v.push_back(0); ` ` ` `v.push_back(2); ` ` ` `v.push_back(3); ` ` ` ` ` `// 1-based indexing ` ` ` `n = v.size() + 1; ` ` ` ` ` `xorr[1] = v[1]; ` ` ` `for` `(` `long` `long` `i = 2; i <= n; ++i) ` ` ` `xorr[i] = xorr[i - 1] ^ v[i]; ` ` ` ` ` `// Queries ` ` ` `queries[1] = Query(1, 6, 1); ` ` ` `queries[2] = Query(2, 4, 2); ` ` ` `queries[3] = Query(2, 6, 3); ` ` ` ` ` `Mo(); ` ` ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

**Output:**

3 0 2

**Time Complexity:** O((n + q) * sqrt(n))

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready.

## Recommended Posts:

- Find the XOR of the elements in the given range [L, R] with the value K for a given set of queries
- Array range queries over range queries
- Queries on XOR of XORs of all subarrays
- Queries on XOR of greatest odd divisor of the range
- Range Update Queries to XOR with 1 in a Binary Array.
- Queries to increment array elements in a given range by a given value for a given number of times
- Queries for elements having values within the range A to B in the given index range using Segment Tree
- Range Queries to count elements lying in a given Range : MO's Algorithm
- Queries to find maximum sum contiguous subarrays of given length in a rotating array
- Find number of subarrays with XOR value a power of 2
- Queries to find the maximum Xor value between X and the nodes of a given level of a perfect binary tree
- Count the number of subarrays having a given XOR
- Given a set, find XOR of the XOR's of all subsets.
- String Range Queries to find the number of subsets equal to a given String
- Find XOR of two number without using XOR operator
- Binary Indexed Tree : Range Update and Range Queries
- Differences between number of increasing subarrays and decreasing subarrays in k sized windows
- Queries to update Subarrays of a given Array using Disjoint Set
- Queries to find the XOR of an Array after replacing all occurrences of X by Y
- Maximize the number of subarrays with XOR as zero

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.