Count Subarrays with given XOR

medium

You're given an array of integers arr and an integer k. Count the number of subarrays whose elements XOR together to exactly k.

A subarray is a contiguous slice of the array — [2, 2, 6] counts, but you can't skip elements.

It is guaranteed that the total count fits within a 32-bit integer.

Hints

Checking every subarray works but is O(n^2). What running quantity could let you describe any subarray using just two values?
XOR cancels itself: a ^ a = 0. So the XOR of arr[i..j] equals prefixXor[j] ^ prefixXor[i-1] — the shared prefix vanishes.
You need prefixXor[i-1] = prefixXor[j] ^ k. Keep a hash map from each prefix XOR value to how many times it has appeared, seeded with {0: 1}, and add freq[prefix ^ k] at every step.

Common doubts

The empty prefix (before any element) has XOR 0. Seeding freq[0] = 1 lets subarrays that start at index 0 find their partner — without it, a whole-array match would be missed.
Several earlier positions can share the same prefix XOR, and each one is the start of a different valid subarray ending here. Adding freq[prefix ^ k] counts all of them at once.
Nothing in the code — but conceptually you are counting pairs of equal prefix snapshots, since prefix ^ 0 = prefix. That is why the update order matters: look up before inserting the current prefix, or it would match itself.
Yes — replace prefix ^= num with prefix += num and look up prefix - k, and you have solved Subarray Sum Equals K. The prefix-plus-hash-map skeleton is identical.

Interview follow-ups

A hash map can only answer equality lookups. For range queries over XOR you switch the data structure to a binary trie of prefix XORs, walking bit by bit and counting whole subtrees that are guaranteed below k.
Store the earliest index of each prefix XOR instead of a frequency. At each position, if prefix ^ k was seen before, the candidate length is the gap to its first occurrence — keep the maximum.
Map each prefix XOR to the list of indices where it occurred. Each stored index i with value prefix ^ k yields the subarray from i + 1 to the current position — but note the output itself can be O(n^2) in size.

Fun facts

  • XOR is the only operator here that is its own inverse — that self-cancellation (a ^ a = 0) is the entire reason prefixes subtract cleanly without any actual subtraction.
  • The prefix-plus-hash-map skeleton is one of the highest-leverage patterns in interviews: it solves Subarray Sum Equals K, Longest Sub-Array with Sum K, and this problem with only the operator swapped.
  • The follow-up world of this trick — XOR range queries — is dominated by binary tries, the same structure behind Maximum XOR of Two Numbers in an Array.

Asked at

AmazonGoogleMicrosoftFlipkartAdobe
Frequently Sometimes Occasionally
Example 1
Input: arr = [4, 2, 2, 6, 4], k = 6
Output: 4
Four subarrays XOR to 6: [4, 2], [4, 2, 2, 6, 4], [2, 2, 6], and [6].
Example 2
Input: arr = [5, 6, 7, 8, 9], k = 5
Output: 2
Only [5] and the full array [5, 6, 7, 8, 9] XOR to 5.
Example 3
Input: arr = [1, 1, 1, 1], k = 0
Output: 4
The three [1, 1] pairs and the whole array [1, 1, 1, 1] each XOR to 0.
Constraints

- 1 <= arr.size <= 10^5 - 0 <= arr[i] <= 10^5 - 0 <= k <= 10^5

Solve this problem →