Subarray with XOR less than k

23 May, 2022
Given an array of n numbers and a number k. You have to write a program to find the number of subarrays with xor less than k.Examples: 
Input:  arr[] = {8, 9, 10, 11, 12},  k=3Output: 4Explaination: Sub-arrays [1:3], [2:3], [2:5], [4:5] have xor values 2, 1, 0, 1 respectively.
Input: arr[] = {12, 4, 6, 8, 21},  k=8Output: 4
Naive Approach: The naive algorithm is to simply calculate the xor value of each and every subarray and compare it with the given number k to find the answer. Below is the implementation of the above approach: 
C++
Java
Python3
C#
PHP
Javascript
// C++ program to count number of// subarrays with XOR less than k#include <iostream>using namespace std; // function to count number of// subarrays with XOR less than kint xorLessK(int arr[], int n, int k){    int count = 0;     // check all subarrays    for (int i = 0; i < n; i++) {        int tempXor = 0;        for (int j = i; j < n; j++) {            tempXor ^= arr[j];            if (tempXor < k)                count++;        }    }     return count;} // Driver program to test above functionint main(){    int n, k = 3;    int arr[] = { 8, 9, 10, 11, 12 };     n = sizeof(arr) / sizeof(arr[0]);     cout << xorLessK(arr, n, k);     return 0;}
// Java program to count number of// subarrays with XOR less than k import java.io.*; class GFG {     // function to count number of// subarrays with XOR less than kstatic int xorLessK(int arr[], int n, int k){    int count = 0;     // check all subarrays    for (int i = 0; i < n; i++) {        int tempXor = 0;        for (int j = i; j < n; j++) {            tempXor ^= arr[j];            if (tempXor < k)                count++;        }    }     return count;} // Driver program to test above function    public static void main (String[] args) {              int k = 3;    int arr[] = new int[] { 8, 9, 10, 11, 12 };    int n = arr.length;     System.out.println(xorLessK(arr, n, k));             }}
# Python 3 program to count number of# subarrays with XOR less than k # function to count number of# subarrays with XOR less than kdef xorLessK(arr, n, k):    count = 0     # check all subarrays    for i in range(n):        tempXor = 0        for j in range(i, n):            tempXor ^= arr[j]            if (tempXor < k):                count += 1         return count # Driver Codeif __name__ == '__main__':    k = 3    arr = [8, 9, 10, 11, 12]     n = len(arr)     print(xorLessK(arr, n, k)) # This code is contributed by# Sahil_shelangia
// C# program to count number of// subarrays with XOR less than kusing System; class GFG {     // function to count number of// subarrays with XOR less than kstatic int xorLessK(int []arr, int n, int k){    int count = 0;     // check all subarrays    for (int i = 0; i < n; i++) {                 int tempXor = 0;                 for (int j = i; j < n; j++) {                         tempXor ^= arr[j];            if (tempXor < k)                count++;        }    }     return count;} // Driver Codestatic public void Main (){             int k = 3;    int []arr = new int[] {8, 9, 10,                           11, 12 };    int n = arr.Length;    Console.WriteLine(xorLessK(arr, n, k));     }}
<?php// PHP program to count number of// subarrays with XOR less than k // function to count number of// subarrays with XOR less than kfunction xorLessK($arr, $n, $k){    $count = 0;     // check all subarrays    for ($i = 0; $i < $n; $i++)    {        $tempXor = 0;        for ($j = $i; $j < $n; $j++)        {            $tempXor ^= $arr[$j];            if ($tempXor < $k)                $count++;        }    }     return $count;}     // Driver Code    $n; $k = 3;    $arr = array(8, 9, 10, 11, 12);     $n = count($arr);     echo xorLessK($arr, $n, $k); // This code is contributed by anuj_67.?>
<script>    // Javascript program to count number of    // subarrays with XOR less than k         // function to count number of    // subarrays with XOR less than k    function xorLessK(arr, n, k)    {        let count = 0;         // check all subarrays        for (let i = 0; i < n; i++) {             let tempXor = 0;             for (let j = i; j < n; j++) {                 tempXor ^= arr[j];                if (tempXor < k)                    count++;            }        }         return count;    }         let k = 3;    let arr = [8, 9, 10, 11, 12];    let n = arr.length;    document.write(xorLessK(arr, n, k));     </script>
3
Time Complexity: . Efficient Approach: An efficient approach will be to calculate all of the prefix xor values i.e. a[1:i] for all i. It can be verified that the xor of a subarray a[l:r] can be written as (a[1:l-1] xor a[1:r]), where a[i, j] is the xor of all the elements with index such that, i <= index <= j. Explanation: We will store a number as a binary number in trie. The left child will show that the next bit is 0 and the right child will show the next bit is 1. For example, the given picture below shows numbers 1001 and 1010 in trie.  
If xor[i, j] represents the xor of all elements in the subarray a[i, j], then at an index i what we have is, a trie which has xor[1:1], xor[1:2].....xor[1:i-1] already inserted. Now we somehow count how many of these (numbers in trie) are such that its xor with xor[1:i] is smaller than k. This will cover all the subarrays ending at the index i and having xor i.e. xor[j, i] <=k;Now the problem remains, how to count the numbers with xor smaller than k. So, for example, take the current bit of the ith index element is p, a current bit of number k be q and the current node in trie be node. Take the case when p=1, k=1. Then if we go to the right child the current xor would be 0 (as the right child means 1 and p=1, 1(xor)1=0).As k=1, all the numbers that are to the right child of this node would give xor value smaller than k. So, we would count the numbers that are right to this node. If we go to the left child, the current xor would be 1 (as the left child means 0 and p=1, 0(xor)1=1). So, if we go to the left child we can still find number with xor smaller than k, therefore we move on to the left child.So, to count the numbers that are below a given node, we modify the trie and each node will also store the number of leafs in that subtree and this would be modified after each insertion.Other three cases for different values of p and k can be solved in the same way to the count the number of numbers with xor less than k.
Below is the C++ implementation of the above idea: 
CPP
#include <iostream>using namespace std;class trienode {public:    int left_count, right_count;    trienode* left;    trienode* right;    trienode()    {        left_count = 0;        right_count = 0;         // Left denotes 0        left = NULL;         // Right denotes 1        right = NULL;    }};void insert(trienode* root, int element){    for (int i = 31; i >= 0; i--) {        int x = (element >> i) & 1;         // If the current bit is 1        if (x) {            root->right_count++;            if (root->right == NULL)                root->right = new trienode();            root = root->right;        }        else {            root->left_count++;            if (root->left == NULL)                root->left = new trienode();            root = root->left;        }    }}int query(trienode* root, int element, int k){    if (root == NULL)        return 0;    int res = 0;    for (int i = 31; i >= 0; i--) {        bool current_bit_of_k = (k >> i) & 1;        bool current_bit_of_element = (element >> i) & 1;         // If the current bit of k is 1        if (current_bit_of_k) {            // If current bit of element is 1            if (current_bit_of_element) {                res += root->right_count;                if (root->left == NULL)                    return res;                root = root->left;            }             // If current bit of element is 0            else {                res += root->left_count;                if (root->right == NULL)                    return res;                root = root->right;            }        }         // If the current bit of k is zero        else {            // If current bit of element is 1            if (current_bit_of_element) {                if (root->right == NULL)                    return res;                root = root->right;            }             // If current bit of element is 0            else {                if (root->left == NULL)                    return res;                root = root->left;            }        }    }    return res;} // Driver codeint main(){     int n = 5, k = 3;    int arr[] = { 8, 9, 10, 11, 12 };     // Below three variables are used for storing    // current XOR    int temp, temp1, temp2 = 0;    trienode* root = new trienode();    insert(root, 0);    long long total = 0;    for (int i = 0; i < n; i++) {        temp = arr[i];        temp1 = temp2 ^ temp;        total += query(root, temp1, k);        insert(root, temp1);        temp2 = temp1;    }     cout << total << endl;     return 0;}
3

Time complexity: O(n*log(max)), where max is the maximum element in the array.Related Articles: 
pair minimum xor value
maximum subarray xor
This article is contributed by Amritya Vagmi. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or if you want to share more information about the topic discussed above. 
vt_m
jit_t
sahilshelangia
rameshtravel07
kuldeepy10459
Bitwise-XOR
Trie
Arrays
Arrays
Trie
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum and minimum of an array using minimum number of comparisons
Top 50 Array Coding Problems for Interviews
Multidimensional Arrays in Java
Stack Data Structure (Introduction and Program)
Linear Search
Introduction to Arrays
K'th Smallest/Largest Element in Unsorted Array | Set 1
Find Second largest element in an array
Introduction to Data Structures
Subset Sum Problem | DP-25