Given an array arr[] , the binary distance between two numbers is defined as the number of positions at which their binary representations differ. For example, the binary of 2 and 7 are 010 and 111 respectively. They differ at two positions(1st bit and 3rd bit), so their distance is 2.
Find the sum of binary distances for all ordered pairs in the array. i.e , compute the sum of all binary distances over every pair (arr[i], arr[j]) where 0 ≤ i, j < arr.length.
Since the answer can be large, return it modulo 109 + 7.
Examples :
Input: arr[] = [2, 4]
Output: 4
Explanation: We return Binary representation of 2 = 010 Binary representation of 4 = 100, Binary distance(2, 2) = 0 Binary distance(2, 4) = 2, Binary distance(4, 2) = 2 Binary distance(4, 4) = 0, Total binary distance = 0 + 2 + 2 + 0 = 4.Input: arr[] = [1, 3, 5]
Output: 8
Explanation: We return, Binary representation of 1 = 001 Binary representation of 3 = 011, Binary representation of 5 = 101 Binary distance(1, 1) = 0 , Binary distance(1, 3) = 1 Binary distance(1, 5) = 1 , Binary distance(3, 1) = 1 Binary distance(3, 3) = 0, Binary distance(3, 5) = 2 Binary distance(5, 1) = 1 , Binary distance(5, 3) = 2 Binary distance(5, 5) = 0, Total binary distance = 0 + 1 + 1 + 1 + 0 + 2 + 1 + 2 + 0 = 8.
[Naive Approach] Using Nested Loops – O(N^2) Time and O(1) Space :
The idea is to run two loops to consider all pairs one by one. For every pair, count bit differences. Finally return sum of counts.
#include <bits/stdc++.h>
using namespace std;
int sumBitDifferences(vector<int> &arr)
{
int n = arr.size();
int ans = 0;
for (int i = 0; i < n - 1; i++) {
int count = 0;
for (int j = i; j < n; j++) {
// Bitwise and of pair (a[i], a[j])
int x = arr[i] & arr[j];
// Bitwise or of pair (a[i], a[j])
int y = arr[i] | arr[j];
bitset<32> b1(x);
bitset<32> b2(y);
// to count set bits in and of two numbers
int r1 = b1.count();
// to count set bits in or of two numbers
int r2 = b2.count();
// Absolute differences at individual bit positions of two
// numbers is contributed by pair (a[i], a[j]) in count
count = abs(r1 - r2);
// each pair adds twice of contributed count
// as both (a, b) and (b, a) are considered
// two separate pairs.
ans = ans + (2 * count);
}
}
return ans;
}
int main()
{
vector<int> nums{ 10, 5 };
int ans = sumBitDifferences(nums);
cout << ans;
}
import java.io.*;
class GFG {
static int sumBitDifferences(int[] arr)
{
int diff = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = i; j < arr.length; j++) {
// XOR toggles the bits and will form a
// number that will have set bits at the
// places where the numbers bits differ eg:
// 010 ^ 111 = 101...diff of bits = count of
// 1's = 2
int xor = arr[i] ^ arr[j];
int count = countSetBits(xor);
// when i == j (same numbers) the xor would
// be 0, thus our ans will remain unaffected
// as (2*0 = 0)
diff += 2 * count;
}
}
return diff;
}
// Kernighan algo
static int countSetBits(int n)
{
int count = 0;
while (n != 0) {
n = n & (n - 1); // clear set LSB
count++;
}
return count;
}
public static void main(String[] args)
{
int[] arr = { 5, 10 };
int ans = sumBitDifferences(arr);
System.out.println(ans);
}
}
# Python3 program for the above approach
def sumBitDifferences(arr):
diff = 0 # hold the ans
for i in range(len(arr)):
for j in range(i, len(arr)):
# XOR toggles the bits and will form a number that will have
# set bits at the places where the numbers bits differ
# eg: 010 ^ 111 = 101...diff of bits = count of 1's = 2
xor = arr[i] ^ arr[j]
count = countSetBits(xor)
# when i == j (same numbers) the xor would be 0,
# thus our ans will remain unaffected as (2*0 = 0)
diff += (2 * count)
return diff
# Kernighan algo
def countSetBits(n):
count = 0
while (n != 0):
n = n & (n - 1)
count += 1
return count
# Driver code
if __name__ == "__main__":
arr = [5, 10]
ans = sumBitDifferences(arr)
print(ans)
/*package whatever //do not write package name here */
using System;
public class GFG {
static int sumBitDiff(int[] arr){
int diff = 0;
for(int i=0; i<arr.Length; i++){
for(int j=i; j<arr.Length; j++){
//XOR toggles the bits and will form a number that will have
//set bits at the places where the numbers bits differ
//eg: 010 ^ 111 = 101...diff of bits = count of 1's = 2
int xor = arr[i]^arr[j];
int count = countSetBits(xor);
//when i == j (same numbers) the xor would be 0,
//thus our ans will remain unaffected as (2*0 = 0)
diff += 2*count;
}
}
return diff;
}
//Kernighan algo
static int countSetBits(int n){
int count = 0;
while (n != 0) {
n = n & (n - 1);
count++;
}
return count;
}
public static void Main(String[] args) {
int[] arr = {5,10};
int ans = sumBitDiff(arr);
Console.WriteLine(ans);
}
}
// This code contributed by umadevi9616
function sumBitDifferences(arr) {
let diff = 0; // hold the ans
for (let i = 0; i < arr.length; i++) {
for (let j = i; j < arr.length; j++) {
// XOR toggles the bits and will form a number that will have
// set bits at the places where the numbers bits differ
// eg: 010 ^ 111 = 101...diff of bits = count of 1's = 2
let xor = arr[i] ^ arr[j];
let count = countSetBits(xor);
// when i == j (same numbers) the xor would be 0,
// thus our ans will remain unaffected as (2*0 = 0)
diff += (2 * count);
}
}
return diff;
}
// Kernighan algo
function countSetBits(n) {
let count = 0;
while (n!= 0) {
n = n & (n - 1);
count += 1;
}
return count;
}
// Driver code
let arr = [5, 10];
let ans = sumBitDifferences(arr);
console.log(ans);
Output
8
[Efficient Approach] Bit Optimization – O(n) Time and O(1) Space
Instead of comparing every pair one by one, we iterate over fixed 32-bit integer range. By examining each of the 32 bit positions separately, we count how many ordered pairs differ at that specific position without explicitly matching the numbers.
- For any given bit position i, we traverse the array to count how many numbers have that particular bit set to 1, denoted as
count. - The remaining
n - countnumbers will have that specific bit unset (0). - An ordered pair contributes exactly 1 to the binary distance only when a number with a set bit is paired with a number with an unset bit.
- To find the total number of valid pairs differing at this bit, we use the formula count * (n - count) * 2. We multiply by 2 because the problem requires us to calculate distances for ordered pairs, meaning both (arr[i], arr[j]) and (arr[j], arr[i]) are counted as distinct pairs.
#include <bits/stdc++.h>
using namespace std;
int sumBitDifferences(vector<int> arr)
{
int n = arr.size(), ans = 0;
// traverse over all bits
for (int i = 0; i < 32; i++) {
// count number of elements with i'th bit set
int count = 0;
for (int j = 0; j < n; j++)
if ((arr[j] & (1 << i)))
count++;
// Add "count * (n - count) * 2" to the answer
ans += (count * (n - count) * 2);
}
return ans;
}
// Driver program
int main()
{
vector<int> arr = { 1, 3, 5 };
cout << sumBitDifferences(arr) << endl;
return 0;
}
import java.util.Arrays;
public class Main {
int sumBitDifferences(int[] arr) {
int n = arr.length, ans = 0;
// traverse over all bits
for (int i = 0; i < 32; i++) {
// count number of elements with i'th bit set
int count = 0;
for (int j = 0; j < n; j++)
if ((arr[j] & (1 << i))!= 0)
count++;
// Add "count * (n - count) * 2" to the answer
ans += (count * (n - count) * 2);
}
return ans;
}
// Driver program
public static void main(String[] args) {
Main ob = new Main();
int[] arr = { 1, 3, 5 };
System.out.println(ob.sumBitDifferences(arr));
}
}
def sumBitDifferences(arr):
n = len(arr)
res = 0
for i in range(32):
# Count elements with i-th bit set
cnt = 0
for x in arr:
if x & (1 << i):
cnt += 1
# Add contribution of this bit
res += cnt * (n - cnt) * 2
return res
arr = [1, 3, 5]
print(sumBitDifferences(arr))
using System;
public class Program {
public int sumBitDifferences(int[] arr) {
int n = arr.Length, ans = 0;
// traverse over all bits
for (int i = 0; i < 32; i++) {
// count number of elements with i'th bit set
int count = 0;
for (int j = 0; j < n; j++)
if ((arr[j] & (1 << i))!= 0)
count++;
// Add "count * (n - count) * 2" to the answer
ans += (count * (n - count) * 2);
}
return ans;
}
// Driver program
public static void Main() {
Program ob = new Program();
int[] arr = { 1, 3, 5 };
Console.WriteLine(ob.sumBitDifferences(arr));
}
}
function sumBitDifferences(arr) {
let n = arr.length;
let res = 0;
for (let i = 0; i < 32; i++) {
// Count elements with i-th bit set
let cnt = 0;
for (let x of arr)
if (x & (1 << i))
cnt++;
// Add contribution of this bit
res += cnt * (n - cnt) * 2;
}
return res;
}
let arr = [1, 3, 5];
console.log(sumBitDifferences(arr));
Output
8