Number of triplets in array having subarray xor equal

Given an array of integers Arr. The task is to count the number of triplets (i, j, k) such that Ai ^ Ai+1 ^ Ai+2 ^ …. ^ Aj-1 = Aj ^ Aj+1 ^ Aj+2 ^ ….. ^ Ak, and 0 < (i, j, k) < N , where N is the size of the array.

Where ^ is the bitwise xor of two numbers.

Examples:



Input: Arr = {5, 2, 7}
Output: 2

The triplets are (0, 2, 2) since 5 ^ 2 = 7 and (0, 1, 2) since 2 ^ 7 = 5.

Input: Arr = {1, 2, 3, 4, 5}
Output: 5

Bruteforce Approach: A simple solution is to run three nested loops iterating through all possible values of i, j and k and then another loop to calculate the xor of both first and second subarray.
The time complexity of this solution is O(N4).

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// A simple C++ program to find Number of triplets
// in array having subarray xor equal
#include <bits/stdc++.h>
using namespace std;
  
// Function to return the count
int xor_triplet(int arr[], int n)
{
    // Initialse result
    int ans = 0;
  
    // Pick 1st element of the triplet
    for (int i = 0; i < n; i++) {
  
        // Pick 2nd element of the triplet
        for (int j = i + 1; j < n; j++) {
  
            // Pick 3rd element of the triplet
            for (int k = j; k < n; k++) {
  
                int xor1 = 0, xor2 = 0;
  
                // Taking xor in the
                // first subarray
                for (int x = i; x < j; x++) {
                    xor1 ^= arr[x];
                }
  
                // Taking xor in the
                // second subarray
                for (int x = j; x <= k; x++) {
                    xor2 ^= arr[x];
                }
  
                // If both xor is equal
                if (xor1 == xor2) {
                    ans++;
                }
            }
        }
    }
    return ans;
}
  
// Driver Code
int main()
{
    int arr[] = { 1, 2, 3, 4, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    // Function Calling
    cout << xor_triplet(arr, n);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find Number of triplets 
// in array having subarray xor equal 
class GFG
{
  
// Function to return the count 
static int xor_triplet(int arr[], int n) 
    // Initialse result 
    int ans = 0
  
    // Pick 1st element of the triplet 
    for (int i = 0; i < n; i++) 
    
  
        // Pick 2nd element of the triplet 
        for (int j = i + 1; j < n; j++)
        
  
            // Pick 3rd element of the triplet 
            for (int k = j; k < n; k++)
            
                int xor1 = 0, xor2 = 0
  
                // Taking xor in the 
                // first subarray 
                for (int x = i; x < j; x++) 
                
                    xor1 ^= arr[x]; 
                
  
                // Taking xor in the 
                // second subarray 
                for (int x = j; x <= k; x++)
                
                    xor2 ^= arr[x]; 
                
  
                // If both xor is equal 
                if (xor1 == xor2) 
                
                    ans++; 
                
            
        
    
    return ans; 
  
// Driver Code 
public static void main (String[] args) 
    int arr[] = { 1, 2, 3, 4, 5 }; 
    int n = arr.length; 
  
    // Function Calling 
    System.out.println(xor_triplet(arr, n)); 
}
  
// This code is contributed by AnkitRai01

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# A simple python3 program to find Number of triplets
# in array having subarray xor equal
  
# Function to return the count
def xor_triplet(arr, n):
      
    # Initialse result
    ans = 0;
  
    # Pick 1st element of the triplet
    for i in range(n):
  
        # Pick 2nd element of the triplet
        for j in range(i + 1, n):
  
            # Pick 3rd element of the triplet
            for k in range(j, n):
  
                xor1 = 0; xor2 = 0;
  
                # Taking xor in the
                # first subarray
                for x in range(i, j):
                    xor1 ^= arr[x];
  
                # Taking xor in the
                # second subarray
                for x in range(j, k + 1):
                    xor2 ^= arr[x];
  
                # If both xor is equal
                if (xor1 == xor2):
                    ans += 1;
  
    return ans;
  
# Driver Code
if __name__ == '__main__':
    arr = [1, 2, 3, 4, 5];
    n = len(arr);
  
    # Function Calling
    print(xor_triplet(arr, n));
      
# This code is contributed by PrinciRaj1992

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find Number of triplets 
// in array having subarray xor equal 
using System;
      
class GFG
{
  
// Function to return the count 
static int xor_triplet(int []arr, int n) 
    // Initialse result 
    int ans = 0; 
  
    // Pick 1st element of the triplet 
    for (int i = 0; i < n; i++) 
    
  
        // Pick 2nd element of the triplet 
        for (int j = i + 1; j < n; j++)
        
  
            // Pick 3rd element of the triplet 
            for (int k = j; k < n; k++)
            
                int xor1 = 0, xor2 = 0; 
  
                // Taking xor in the 
                // first subarray 
                for (int x = i; x < j; x++) 
                
                    xor1 ^= arr[x]; 
                
  
                // Taking xor in the 
                // second subarray 
                for (int x = j; x <= k; x++)
                
                    xor2 ^= arr[x]; 
                
  
                // If both xor is equal 
                if (xor1 == xor2) 
                
                    ans++; 
                
            
        
    
    return ans; 
  
// Driver Code 
public static void Main (String[] args) 
    int []arr = { 1, 2, 3, 4, 5 }; 
    int n = arr.Length; 
  
    // Function Calling 
    Console.WriteLine(xor_triplet(arr, n)); 
}
  
// This code is contributed by PrinciRaj1992

chevron_right


Output:

5

Efficient Approach:

  • An efficient solution is to use Trie.
  • One observatoion is that if the subarray from i to k have Ai ^ Ai+1 ^ …. ^ Ak = 0 then we can select any j such that i < j <= k and that will always satisfy our condition.
  • This observation will be used to calculate the number of triplets.
  • We will take the cumulative xor of the elements in the array and check that this xor value exists in the Trie or not.
    1. If the xor already exists in the Trie then we have encounted a subarray having 0 xor and count all the triplets.
    2. Else push the value of xor into the Trie.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ trie based program to find the Number of
// triplets in array having subarray xor equal
#include <bits/stdc++.h>
using namespace std;
  
// maximum number of bits
// in an integer <= 1e9
#define lg 31
  
// Structure of a Trie Node
struct TrieNode {
  
    // [0] index is bit 0
    // and [1] index is bit 1
    TrieNode* children[2];
  
    // Sum of indexes
    // inserted at at a node
    int sum_of_indexes;
  
    // Number of indexes
    // inserted at a node
    int number_of_indexes;
  
    // Constructor to initialize
    // a newly created node
    TrieNode()
    {
  
        this->children[0] = nullptr;
        this->children[1] = nullptr;
        this->sum_of_indexes = 0;
        this->number_of_indexes = 0;
    }
};
  
// Function to insert curr_xor
// into the trie
void insert(TrieNode* node,
            int num,
            int index)
{
  
    // Iterate from the 31st bit
    // to the 0th bit of curr_xor
    // number
    for (int bits = lg; bits >= 0; bits--) {
  
        // Check if the current
        // bit is set or not
        int curr_bit = (num >> bits) & 1;
  
        // If this node isn't already
        // present in the trie structure
        // insert it into the trie.
        if (node->children[curr_bit]
            == nullptr) {
            node->children[curr_bit]
                = new TrieNode();
        }
  
        node = node->children[curr_bit];
    }
  
    // Increase the sum of
    // indexes by the current
    // index value
    node->sum_of_indexes += index;
  
    // Increase the number
    // of indexes by 1
    node->number_of_indexes++;
}
  
// Function to check if curr_xor
// is present in trie or not
int query(TrieNode* node,
          int num,
          int index)
{
  
    // Iterate from the 31st bit
    // to the 0th bit of curr_xor number
    for (int bits = lg; bits >= 0; bits--) {
  
        // Check if the current bit
        // is set or not
        int curr_bit = (num >> bits) & 1;
  
        // If this node isn't already
        // present in the trie structure
        // that means no sub array till
        // current index has 0 xor so
        // return 0
        if (node->children[curr_bit]
            == nullptr) {
            return 0;
        }
  
        node = node->children[curr_bit];
    }
  
    // Calculate the number of index
    // inserted at final node
    int sz = node->number_of_indexes;
  
    // Calculate the sum of index
    // inserted at final node
    int sum = node->sum_of_indexes;
  
    int ans = (sz * index) - (sum);
  
    return ans;
}
  
// Function to return the count of
// valid triplets
int no_of_triplets(int arr[], int n)
{
  
    // To store cumulative xor
    int curr_xor = 0;
  
    int number_of_triplets = 0;
  
    // The root of the trie
    TrieNode* root = new TrieNode();
  
    for (int i = 0; i < n; i++) {
  
        int x = arr[i];
  
        // Insert the curr_xor in the trie
        insert(root, curr_xor, i);
  
        // Update the cumulative xor
        curr_xor ^= x;
  
        // Check if the cumulative xor
        // is present in the trie or not
        // if present then add
        // (sz * index) - sum
        number_of_triplets
            += query(root, curr_xor, i);
    }
  
    return number_of_triplets;
}
  
// Driver Code
int main()
{
    // Given array
    int arr[] = { 5, 2, 7 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    cout << no_of_triplets(arr, n);
  
    return 0;
}

chevron_right


Output:

2

Time complexity: O(31*N)



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

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.



Improved By : AnkitRai01, princiraj1992