Количество троек в массиве, имеющем подмассив xor, равный
Учитывая массив целых чисел 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 <j≤ k <N , где N - размер массива.
Где ^ - это побитовый xor двух чисел.
Примеры:
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
Подход грубой силы: простое решение - запустить три вложенных цикла, повторяющих все возможные значения i , j и k, а затем еще один цикл для вычисления xor как первого, так и второго подмассива.
Временная сложность этого решения составляет O (N 4 ) .
Эффективный подход:
- Эффективное решение - использовать Trie.
- Одно наблюдение состоит в том, что если подмассив от i до k имеет A i ^ A i + 1 ^…. ^ A k = 0, тогда мы можем выбрать любое j такое, что i <j <= k, и это всегда будет удовлетворять нашему условию.
- Это наблюдение будет использовано для расчета количества троек.
- Мы возьмем кумулятивный xor элементов в массиве и проверим, существует ли это значение xor в Trie или нет.
- Если xor уже существует в Trie, то мы включили подмассив, имеющий 0 xor, и подсчитали все триплеты.
- В противном случае поместите значение xor в Trie .
Below is the implementation of the above approach:
C++
// 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; } |
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)
Вниманию читателя! Не прекращайте учиться сейчас. Освойте все важные концепции DSA с помощью самостоятельного курса DSA по приемлемой для студентов цене и будьте готовы к работе в отрасли. Чтобы завершить подготовку от изучения языка к DS Algo и многому другому, см. Полный курс подготовки к собеседованию .
Если вы хотите посещать живые занятия с отраслевыми экспертами, пожалуйста, обращайтесь к Geeks Classes Live и Geeks Classes Live USA.