Number of ordered pairs such that Ai & Aj = 0


Suppose you are given an array and you have to find the total count of ordered pairs formed such that Ai & Aj = 0.

You are given an array A[A1, A2, A3,…An]. You have to find ordered pairs of Ai and Aj such that their bitwise AND operation will give the result equal to 0. In other words, you have to count the pairs of elements (i, j) whose bitwise AND operation is zero.

For example, we have an array [3, 4, 2]. The binary representation of each element are as follows −

  • A1 = 3 = 011

  • A2 = 4 = 100

  • A3 = 2 = 010

The pairs of AND bitwise operations are −

A1 & A2 = 0, A2 & A3 = 0, A2 & A1 = 0, A3 & A2 = 0

For rest of the pairs, the result is non-zero. Hence, we have to find such pairs which gives the result 0.

Input Output Scenarios

We are given N. The number of N digit non-decreasing integers is the output.

Input: arr[] = {1, 5, 4, 3}
Output: 4
Input: arr[] = {11, 5, 20, 6, 3}
Output: 10

Using Iteration

We can simply iterate through all the possible pairs of the elements of array and do bitwise AND operation on them. If the result is 0, then count variable is increased by two. This is because if the result is zero for (i, j), it will be the same for (j, i). Here, (i, j) and (j, i) are considered different.

Example

#include <iostream>
using namespace std;
int possiblePairs(int arr[], int N){
   int count = 0;
   for(int j = 0; j < N; j++){
      for(int k = j + 1; k < N; k++){
         if((arr[j] & arr[k]) == 0){
            count += 2;
         }
      }
   }
   return count;
}
int main(){
   int arr[] = {1, 5, 4, 3};
   int N = sizeof(arr) / sizeof(arr[0]);
   cout << "Number of ordered pairs such that (arr[j] & arr[k] = 0) is " <<
   possiblePairs(arr, N) << endl;
   return 0;
}

Output

Number of ordered pairs such that (arr[j] & arr[k] = 0) is 4

Using ‘unordered_map’ Data Structure

We will use the unordered_map data structure to calculate the total count of such pairs. We will use the concept of hashing to easily locate our data records. In the nested loop, the result of the bitwise AND operation is stored in an unordered map. From this map, the data is retrieved and stored in the count variable.

Example

#include <iostream>
#include <unordered_map>
using namespace std;
int possiblePairs(int arr[], int N) {
   unordered_map < int, int > result;
   for (int j = 0; j < N; j++) {
      for (int k = 0; k < N; k++) {
         if ((arr[j] & arr[k]) == 0) {
            result[arr[j]]++;
         }
      }
   }
   int count = 0;
   for (auto it: result) {
      count += it.second;
   }
   return count;
}
int main() {
   int arr[] = { 1, 5, 4, 3 };
   int N = sizeof(arr) / sizeof(arr[0]);
   cout << "Number of ordered pairs such that (arr[j] & arr[k] = 0) is " <<
   possiblePairs(arr, N) << endl;
   return 0;
}

Output

Number of ordered pairs such that (arr[j] & arr[k] = 0) is 4

Using Bitmask and 2D Arrays

We have used the unordered_map to store the frequency of the elements of array. They have keys and values in integer form. We have used the 2D array da to store the intermediary results. Next, we have used bitmask to represent binary representation of the elements in the form of subset of those array elements.

We, then, iterate through all the values of mask to check the bitwise AND operation between the pairs of the elements. Using the bitwise calculation and the 2D array, we find the total count of such pairs.

Example

#include <iostream>
#include <cstring>
#include <unordered_map>
using namespace std;
const int X = 15;
long long possiblePairs(int arr[], int N) {
   // Declaration
   unordered_map<int, int> num;
   long long da[1 << X][X + 1];
   // Initialize all values to 0
   memset(da, 0, sizeof(da));
   for (int i = 0; i < N; ++i)
   num[arr[i]]++;
   for (long long mask = 0; mask < (1 << X); ++mask) {
      if (mask & 1)
      da[mask][0] = num[mask] + num[mask ^ 1];
      else
      da[mask][0] = num[mask];
      for (int i = 1; i <= X; ++i) {
         if (mask & (1 << i))
         da[mask][i] = da[mask][i - 1] +
         da[mask ^ (1 << i)][i - 1];
         else
         da[mask][i] = da[mask][i - 1];
      }
   }
   long long result = 0;
   for (int i = 0; i < N; i++)
   result += da[((1 << X) - 1) ^ arr[i]][X];
   return result;
}
int main() {
   int arr[] = {1, 5, 4, 3};
   int N = sizeof(arr) / sizeof(arr[0]);
   cout << "Number of ordered pairs such that (arr[j] & arr[k] = 0) is " <<
   possiblePairs(arr, N) << endl;
   return 0;
}

Output

Number of ordered pairs such that (arr[j] & arr[k] = 0) is 4

Conclusion

We have discussed about different ways to find the count of ordered pairs such that Ai & Aj = 0. The first approach is a simple one using the nested for loops. The second approach uses ‘unordered_map’ data structure and is a space optimized method. In the third approach, we use bitmask function and 2D arrays making the code more efficient.

Updated on: 05-Jan-2024

33 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements