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:
- Maintain a bit array of size 30. 0th position from left means 2^29 is included in binary representation &, 29th position from left means 2^0 is included in binary representation.
- For each element, if the ith bit is set then increment the ith position of the bit array.
- After encountering the MSB containing ‘1’ calculate the ‘0’ and ‘1’ bits.
- Until a ‘1’ bit is encountered, all the ‘0’ bits will be wasted bits. Store them separately.
- Finally, let’s say for an ith position there is y number of ones. Therefore, there are y*(y-1)/2 pairs for an ith bit having (1, 1) bit combination which gives result 1 as XNOR. Also, let’s say till the same position there is x number of zeroes. Therefore, there are y*(y-1)/2 pairs for an ith bit having (0, 0) bit combination which gives result 1 as XNOR.
- Now for the case of leading zeroes, multiply the number of wasted bits with the number of 0 bits. Do this for each bit position and calculate the answer.
For better understanding, Consider the array {35, 42, 27, 69}. Here are the binary representations of all four elements of the array.
- The one-pointed with the arrow is the first bit of that element which is 1. Hence it is the most significant bit for that element. Similarly, MSB for all other elements is colored green.
- The zeroes appearing before the MSB are wasted bits and colored in red. The size of these binary arrays are 30 each.
- In the first 23 positions of the bits array, the number of wasted bits are four, and the number of 1’s are zero, and the number of 0’s are zero, as seen in the picture.
- In the 24th position, wasted bits are 3, and the number of 1’s will be 1 as MSB is encountered at the 24th element of element 69.
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
- Now in each of these bits, for the XNOR value to be 1 in any of the pair of bits, either both should be 1, or both should be 0.
- For both should be 1, it has N[i]*(N[i]-1)/2 pairs, where N[i] is the number of 1’s in ith position in all the elements.
- Similarly, for both should be 0, it has M[i]*(M[i]-1)/2 pairs, where M[i] is the number of 0’s in ith position in all the elements. Since the required answer is the sum of all possibilities. So, for an ith bit, add 2^(30-i-1) for all possible pairs.
- In case both should be 0, also consider wasted bits which occur in where any of the elements have a 0 (non-wasted) in the same position of the wasted bits. Let the wasted bits be W[i].
- So total sum = (N[i]*(N[i]-1)/2)*(2^(30-i-1) + (M[i]*(M[i]-1)/2)*(2^(30-i-1) + (W[i]*M[i]*(2^(30-i-1))) where 0<= i <=30.
- So, for the above example, till 23rd bit, everything is 0. From 24th bit is listed here.
- total = ((1*0)/2)*(2^6) + ((0*(-1))/2)*(2^6) + 3*0*(2^6) + ((2*1)/2)*(2^5) + ((1*0)/2)*(2^5) + 1*1*(2^5) + ((1*0)/2)*(2^4) + ((3*2)/2)*(2^4) + 0*3*(2^4) + ((2*1)/2)*(2^3) + ((2*1)/2)*(2^3) + 0*2*(2^3) + ((1*0)/2)*(2^2) + ((3*2)/2)*(2^2) + 0*3*(2^2) + ((3*2)/2)*(2^1) + ((1*0)/2)*(2^1) + 0*1*(2^1) + ((3*2)/2)*(2^0) + ((1*0)/2)*(2^0) + 0*1*(2^0)
- total = 0 + 0 + 0 + 32 + 0 + 32 + 0 + 48 + 0 + 8 + 8 + 0 + 0 + 12 + 0 + 6 + 0 + 0 + 3 + 0 + 0
- Therefore, total sum = 149
Below is the implementation of the above approach.
C++
#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. |
Java
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)); } } |
Python3
# 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#
// 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. |
Javascript
<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> |
10
Time Complexity: O(30*N)
Auxiliary Space: O(1)