📜  子数组xor相等的数组中的三元组数

📅  最后修改于: 2021-04-17 13:27:22             🧑  作者: Mango

给定一个整数数组Arr 。任务是计算三元组(i,j,k)的数量,以使A i ^ A i + 1 ^ A i + 2 ^…。 ^ A j-1 = A j ^ A j + 1 ^ A j + 2 ^….. ^ A k ,并且0≤i ,其中N是数组的大小。
其中^是两个数字的按位异或。

例子:

蛮力方法:一个简单的解决方案是运行三个嵌套循环,依次遍历ijk的所有可能值,然后运行另一个循环以计算第一个和第二个子数组的异或。
该解决方案的时间复杂度为O(N 4 )

C++
// A simple C++ program to find Number of triplets
// in array having subarray xor equal
#include 
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;
}


Java
// 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


Python3
# 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


C#
// 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


C++
// C++ trie based program to find the Number of
// triplets in array having subarray xor equal
#include 
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;
}


Java
// Java trie based program to find the Number of
// triplets in array having subarray xor equal
class GFG
{
     
// maximum number of bits
// in an integer <= 1e9
static int lg = 31;
 
// Structure of a Trie Node
static class TrieNode
{
 
    // [0] index is bit 0
    // and [1] index is bit 1
    TrieNode children[];
 
    // 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()
    {
        children = new TrieNode[2];
        this.children[0] = null;
        this.children[1] = null;
        this.sum_of_indexes = 0;
        this.number_of_indexes = 0;
    }
};
 
// Function to insert curr_xor
// into the trie
static 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]
            == null)
        {
            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
static 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]
            == null)
        {
            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
static 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
public static void main(String args[])
{
    // Given array
    int arr[] = { 5, 2, 7 };
    int n = arr.length;
 
    System.out.println(no_of_triplets(arr, n));
}
}
 
// This code is contributed by Arnab Kundu


输出
5

高效方法:

  • 一个有效的解决方案是使用Trie
  • 一种观察是,如果从ik的子数组具有A i ^ A i + 1 ^…。 ^ a k = 0,那么我们可以选择任何j ,使i 且始终满足我们的条件。
  • 该观察将用于计算三元组的数量。
  • 我们将获取数组中元素的累加xor,并检查Trie中是否存在此xor值
    1. 如果在Trie中已经存在xor,那么我们就算出一个具有0 xor的子数组,并计算所有三元组。
    2. 否则将xor的值推入Trie中

下面是上述方法的实现:

C++

// C++ trie based program to find the Number of
// triplets in array having subarray xor equal
#include 
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;
}

Java

// Java trie based program to find the Number of
// triplets in array having subarray xor equal
class GFG
{
     
// maximum number of bits
// in an integer <= 1e9
static int lg = 31;
 
// Structure of a Trie Node
static class TrieNode
{
 
    // [0] index is bit 0
    // and [1] index is bit 1
    TrieNode children[];
 
    // 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()
    {
        children = new TrieNode[2];
        this.children[0] = null;
        this.children[1] = null;
        this.sum_of_indexes = 0;
        this.number_of_indexes = 0;
    }
};
 
// Function to insert curr_xor
// into the trie
static 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]
            == null)
        {
            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
static 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]
            == null)
        {
            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
static 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
public static void main(String args[])
{
    // Given array
    int arr[] = { 5, 2, 7 };
    int n = arr.length;
 
    System.out.println(no_of_triplets(arr, n));
}
}
 
// This code is contributed by Arnab Kundu
输出
2

时间复杂度: O(31 * N)