Open In App

Find sum of XNOR of all unordered pairs from given Array

Given an array arr[] of size N, the task is to find the sum of all XNOR values of all possible unordered pairs from the given array.

Examples:



Input: N = 5, arr[] = {2, 2, 2, 1, 1}
Output:10
Explanation: Here, 
2 XNOR 2 = 3, 2 XNOR 2 = 3, 2 XNOR 2 = 3, 1 XNOR 1 = 1, 2 XNOR 1 = 0, 2 XNOR 1 = 0, 2 XNOR 1 = 0, 2 XNOR 1 = 0, 2 XNOR 1 = 0, 2 XNOR 1 = 0, Therefore sum is 3+3+3+1=10.

Input: N = 3, arr[] = {1, 2, 3}
Output: 3
Explanation: Here, 1 XNOR 2 = 0, 1 XNOR 3 = 1, 2 XNOR 3 = 2. Therefore sum is 0+1+2 = 3



 

Approach: The only possible case for a bit to be set after the XNOR operation is that both the bits must be the same. Follow the below steps to solve the problem:

For better understanding, Consider the array {35, 42, 27, 69}. Here are the binary representations of all four elements of the array.

Binary representations of array elements.

23rd bit: No. of wasted bits: 4, No. of 1’s: 0, No.of 0’s: 0
24th bit: No. of wasted bits: 3, No. of 1’s: 1, No.of 0’s: 0
25th bit: No. of wasted bits: 1, No. of 1’s: 2, No.of 0’s: 1 ( since it occurs after MSB )
26th bit: No. of wasted bits: 0, No. of 1’s: 1, No.of 0’s: 3
27th bit: No. of wasted bits: 0, No. of 1’s: 2, No.of 0’s: 2
28th bit: No. of wasted bits: 0, No. of 1’s: 1, No.of 0’s: 3
29th bit: No. of wasted bits: 0, No. of 1’s: 3, No.of 0’s: 1
30th bit: No. of wasted bits: 0, No. of 1’s: 3, No.of 0’s: 1

Below is the implementation of the above approach.




#include <bits/stdc++.h>
using namespace std;
 
// Function to find the required sum
int findSum(int n, int r[])
{
  // Store the result
  int result = 0;
 
  // bits[i][0] and bits[i][1] has
  // count of all 1's and 0's in the
  // ith bit of all elements respectively
  // bits[i][2] has count of wasted zeroes
  // of ith bit for all elements
  int bits[30][3];
  memset(bits, 0, sizeof(bits));
 
  // Iterating through all elements
  for (int i = 0; i < n; i++) {
    int num = r[i];
 
    // Flag variable set to 1 after
    // first occurrence of 1 (MSB)
    int flag = 0;
 
    // Iterating through all the bits
    for (int j = 29; j >= 0; j--) {
 
      // If msb not found
      if (flag == 0) {
        // Msb found
        if (num >= pow(2, j)) {
 
          // Set flag to 1
          flag = 1;
          num -= pow(2, j);
          bits[29 - j][0]++;
        }
        else {
          bits[29 - j][2]++;
        }
        // Continue till msb is encountered
        continue;
      }
 
      // Incrementing number
      // of 1's in jth bit
      if (num >= pow(2, j)) {
        num -= pow(2, j);
        bits[29 - j][0]++;
      }
      else {
 
        // Incrementing number
        // of 0's in jth bit
        bits[29 - j][1]++;
      }
    }
  }
 
  // Iterating through all bits
  for (int i = 0; i < 30; i++) {
 
    // Total number of 1's in
    // ith bit of all elements
    int y = bits[i][0];
 
    // Total number of 0's in
    // ith bit of all elements
    int x = bits[i][1];
 
    // Total number of wasted 0's
    // before msb of ith bit of all elements
    int msboff = bits[i][2];
 
    // y*(y-1)/2 pairs for ith bit has (1, 1)
    // bit combo which gives result 1 in XNOR
    int onePairs = (y * (y - 1)) / 2;
 
    // Adding value of ith
    // bit number of (1, 1) pairs
    // times to result
    // (2^(30-i-1) => 2 ^ 29, 2 ^ 28 etc.
    result += onePairs * pow(2, 30 - i - 1);
 
    // x*(x-1)/2 pairs for ith bit has (0, 0)
    // bit combo which gives result 1 in XNOR
    int zeroPairs = (x * (x - 1)) / 2;
    result += zeroPairs * pow(2, 30 - i - 1);
 
    result += (msboff * x) * pow(2, 30 - i - 1);
  }
 
  return result;
}
 
// Driver code
int main()
{
  int n = 5;
  int r[5] = { 2, 2, 2, 1, 1 };
 
  // Function call
  cout << findSum(n, r) << endl;
  return 0;
}
 
// This code is contributed by phasing17.




class Main {
    // Function to find the required sum
    static int findSum(int n, int[] r) {
 
        // Store the result
        int result = 0;
 
        // bits[i][0] and bits[i][1] has
        // count of all 1's and 0's in the
        // ith bit of all elements respectively
        // bits[i][2] has count of wasted zeroes
        // of ith bit for all elements
        int[][] bits = new int[30][3];
 
        // Iterating through all elements
        for (int i : r) {
 
            // Converting element to binary
            String binary = Integer.toBinaryString(i);
 
            // zfill adds zeros to the front
            binary = String.format("%30s", binary).replace(' ', '0');
 
            // Flag variable set to 1 after
            // first occurrence of 1 (MSB)
            int flag = 0;
 
            // Iterating through all the bits
            for (int j = 0; j < 30; j++) {
                // If msb not found
                if (flag == 0) {
 
                    // Msb found
                    if (binary.charAt(j) == '1') {
 
                        // Set flag to 1
                        flag = 1;
 
                        // Incrementing number
                        // of 1's in jth bit
                        bits[j][0] += 1;
 
                    } else {
                        // Incrementing number of
                        // wasted zeroes before msb
                        bits[j][2] += 1;
                    }
                    // Continue till msb is encountered
                    continue;
                }
 
                // Incrementing number
                // of 1's in jth bit
                if (binary.charAt(j) == '1') {
                    bits[j][0] += 1;
                } else {
                    // Incrementing number
                    // of 0's in jth bit
                    bits[j][1] += 1;
                }
            }
        }
 
        // Iterating through all bits
        for (int i = 0; i < 30; i++) {
 
            // Total number of 1's in
            // ith bit of all elements
            int y = bits[i][0];
 
            // Total number of 0's in
            // ith bit of all elements
            int x = bits[i][1];
 
            // Total number of wasted 0's
            // before msb of ith bit of all elements
            int msboff = bits[i][2];
 
            // y*(y-1)/2 pairs for ith bit has (1, 1)
            // bit combo which gives result 1 in XNOR
            int onePairs = (y * (y - 1)) / 2;
 
            // Adding value of ith
            // bit number of (1, 1) pairs
            // times to result
            // (2^(30-i-1) => 2 ^ 29, 2 ^ 28 etc.
            result += onePairs * (int) Math.pow(2, 30 - i - 1);
 
            // x*(x-1)/2 pairs for ith bit has (0, 0)
            // bit combo which gives result 1 in XNOR
            int zeroPairs = ((x*(x-1))/2);
            result += zeroPairs * Math.pow(2, 30-i-1);
 
            result += (msboff * x)* Math.pow(2, 30-i-1);
        }
 
    return result;
    }
    public static void main(String[] args) {
    int n = 5;
    int[] r = {2, 2, 2, 1, 1};
    System.out.println(findSum(n, r));
}
 
}




# Python program for the above approach
 
# Function to find the required sum
 
 
def findSum(n, r):
 
    # Store the result
    result = 0
 
    # bits[i][0] and bits[i][1] has
    # count of all 1's and 0's in the
    # ith bit of all elements respectively
    # bits[i][2] has count of wasted zeroes
    # of ith bit for all elements
    bits = [[0, 0, 0] for i in range(30)]
 
    # Iterating through all elements
    for i in r:
 
        # Converting element to binary
        binary = bin(i)[2:]
 
        # zfill adds zeros to the front
        binary = binary.zfill(30)
 
        # Flag variable set to 1 after
        # first occurrence of 1 (MSB)
        flag = 0
 
        # Iterating through all the bits
        for j in range(30):
            # If msb not found
            if(flag == 0):
 
                # Msb found
                if(binary[j] == '1'):
 
                    # Set flag to 1
                    flag = 1
 
                    # Incrementing number
                    # of 1's in jth bit
                    bits[j][0] += 1
 
                # If msb not found yet
                else:
                    # Incrementing number of
                    # wasted zeroes before msb
                    bits[j][2] += 1
 
                # Continue till msb is encountered
                continue
 
            # Incrementing number
            # of 1's in jth bit
            if(binary[j] == '1'):
                bits[j][0] += 1
 
            # Incrementing number
            # of 0's in jth bit
            else:
                bits[j][1] += 1
 
    # Iterating through all bits
    for i in range(30):
 
        # Total number of 1's in
        # ith bit of all elements
        y = bits[i][0]
 
        # Total number of 0's in
        # ith bit of all elements
        x = bits[i][1]
 
        # Total number of wasted 0's
        # before msb of ith bit of all elements
        msboff = bits[i][2]
 
        # y*(y-1)/2 pairs for ith bit has (1, 1)
        # bit combo which gives result 1 in XNOR
        onePairs = (y*(y-1))//2
 
        # Adding value of ith
        # bit number of (1, 1) pairs
        # times to result
        # (2^(30-i-1) => 2 ^ 29, 2 ^ 28 etc.
        result += onePairs * pow(2, 30-i-1)
 
        # x*(x-1)/2 pairs for ith bit has (0, 0)
        # bit combo which gives result 1 in XNOR
        zeroPairs = ((x*(x-1))//2)
 
        # Adding value of ith bit
        # number of (0, 0) pairs
        # times to result
        # (2^(30-i-1) => 2 ^ 29, 2 ^ 28 etc.)
        result += zeroPairs * pow(2, 30-i-1)
 
        # Same for leading zeroes
        result += (msboff * x)*pow(2, 30-i-1)
 
    return result
 
 
# Driver code
if __name__ == '__main__':
    n = 5
    r = [2, 2, 2, 1, 1]
    print(findSum(n, r))




// C# code implementation for the abvoe approach
using System;
 
public class GFG {
 
  // Function to find the required sum
  static int findSum(int n, int[] r)
  {
    // Store the result
    int result = 0;
 
    // bits[i][0] and bits[i][1] has
    // count of all 1's and 0's in the
    // ith bit of all elements respectively
    // bits[i][2] has count of wasted zeroes
    // of ith bit for all elements
    int[, ] bits = new int[30, 3];
 
    // Iterating through all elements
    for (int i = 0; i < r.Length; i++) {
      // Converting element to binary
      string binary
        = Convert.ToString(r[i], 2).PadLeft(30,
                                            '0');
 
      // Flag variable set to 1 after
      // first occurrence of 1 (MSB)
      int flag = 0;
 
      // Iterating through all the bits
      for (int j = 0; j < 30; j++) {
        // If msb not found
        if (flag == 0) {
          // Msb found
          if (binary[j] == '1') {
            // Set flag to 1
            flag = 1;
 
            // Incrementing number
            // of 1's in jth bit
            bits[j, 0] += 1;
          }
          else {
            // Incrementing number of
            // wasted zeroes before msb
            bits[j, 2] += 1;
          }
          // Continue till msb is encountered
          continue;
        }
 
        // Incrementing number
        // of 1's in jth bit
        if (binary[j] == '1') {
          bits[j, 0] += 1;
        }
        else {
          // Incrementing number
          // of 0's in jth bit
          bits[j, 1] += 1;
        }
      }
    }
 
    // Iterating through all bits
    for (int i = 0; i < 30; i++) {
      // Total number of 1's in
      // ith bit of all elements
      int y = bits[i, 0];
 
      // Total number of 0's in
      // ith bit of all elements
      int x = bits[i, 1];
 
      // Total number of wasted 0's
      // before msb of ith bit of all elements
      int msboff = bits[i, 2];
 
      // y*(y-1)/2 pairs for ith bit has (1, 1)
      // bit combo which gives result 1 in XNOR
      int onePairs = (y * (y - 1)) / 2;
 
      // Adding value of ith
      // bit number of (1, 1) pairs
      // times to result
      // (2^(30-i-1) => 2 ^ 29, 2 ^ 28 etc.
      result
        += onePairs * (int)Math.Pow(2, 30 - i - 1);
 
      // x*(x-1)/2 pairs for ith bit has (0, 0)
      // bit combo which gives result 1 in XNOR
      int zeroPairs = ((x * (x - 1)) / 2);
      result
        += zeroPairs * (int)Math.Pow(2, 30 - i - 1);
 
      result += (msboff * x)
        * (int)Math.Pow(2, 30 - i - 1);
    }
    return result;
  }
 
  static public void Main()
  {
 
    // Code
    int n = 5;
    int[] r = { 2, 2, 2, 1, 1 };
    Console.WriteLine(findSum(n, r));
  }
}
 
// This code is contributed by lokeshmvs21.




<script>
    // JavaScript program for the above approach
 
    // Function to find the required sum
    const findSum = (n, r) => {
 
        // Store the result
        let result = 0;
 
        // bits[i][0] and bits[i][1] has
        // count of all 1's and 0's in the
        // ith bit of all elements respectively
        // bits[i][2] has count of wasted zeroes
        // of ith bit for all elements
        let bits = new Array(30).fill(0).map(() => new Array(3).fill(0));
        // Iterating through all elements
        for (let i in r) {
 
            // Converting element to binary
            let binary = Number(r[i]).toString(2);
            binary = binary.split("");
            while (binary.length < 30) {
                binary.unshift('0');
            }
            // Flag variable set to 1 after
            // first occurrence of 1 (MSB)
            let flag = 0;
 
            // Iterating through all the bits
            for (let j = 0; j < 30; j++) {
                // If msb not found
                if (flag == 0) {
 
                    // Msb found
                    if (binary[j] == '1') {
 
                        // Set flag to 1
                        flag = 1;
 
                        // Incrementing number
                        // of 1's in jth bit
                        bits[j][0] += 1;
                    }
 
                    // If msb not found yet
                    else
                        // Incrementing number of
                        // wasted zeroes before msb
                        bits[j][2] += 1;
 
                    // Continue till msb is encountered
                    continue;
                }
 
                // Incrementing number
                // of 1's in jth bit
                if (binary[j] == '1')
                    bits[j][0] += 1;
 
                // Incrementing number
                // of 0's in jth bit
                else
                    bits[j][1] += 1;
            }
        }
        // document.write(`${bits}<br/>`)
        // Iterating through all bits
        for (let i = 0; i < 30; i++) {
 
            // Total number of 1's in
            // ith bit of all elements
            let y = bits[i][0];
 
 
            // Total number of 0's in
            // ith bit of all elements
            let x = bits[i][1];
 
            // Total number of wasted 0's
            // before msb of ith bit of all elements
            let msboff = bits[i][2];
 
            // y*(y-1)/2 pairs for ith bit has (1, 1)
            // bit combo which gives result 1 in XNOR
            let onePairs = (y * (y - 1)) / 2;
            // Adding value of ith
            // bit number of (1, 1) pairs
            // times to result
            // (2^(30-i-1) => 2 ^ 29, 2 ^ 28 etc.
            result += onePairs * Math.pow(2, 30 - i - 1);
 
            // x*(x-1)/2 pairs for ith bit has (0, 0)
            // bit combo which gives result 1 in XNOR
            let zeroPairs = (x * (x - 1)) / 2;
 
            // Adding value of ith bit
            // number of (0, 0) pairs
            // times to result
            // (2^(30-i-1) => 2 ^ 29, 2 ^ 28 etc.)
            result += zeroPairs * Math.pow(2, 30 - i - 1);
 
            // Same for leading zeroes
            result += (msboff * x) * Math.pow(2, 30 - i - 1);
        }
 
        return result;
    }
 
    // Driver code
    let n = 5;
    let r = [2, 2, 2, 1, 1];
    document.write(findSum(n, r));
 
// This code is contributed by rakeshsahni
 
</script>

Output
10

Time Complexity: O(30*N)
Auxiliary Space: O(1)


Article Tags :