XOR of pairwise sum of every unordered pairs in an array
Given an array arr[] of length N, the task is to find the XOR of pairwise sum of every possible unordered pairs of the array. The unordered pairs sum is defined as follows –
XOR of pairwise sum = (A[0] + A[1]) ^
(A[0] + A[2]) ^ ...(A[0] + A[N]) ^
(A[1] + A[2]) ^ ...(A[1] + A[N]) ^
.......
(A[N-1] + A[N])
Notice that after including A[0] and A[1]
as pairs, then A[1] and A[0] are not included.
Examples:
Input: arr[] = {1, 2}
Output: 3
Explanation:
There is only one unordered pair. That is (1, 2)
Input: arr[] = {1, 2, 3}
Output: 2
Explanation:
Unordered pairs of the numbers –
{(1, 2), (1, 3), (2, 3)}
XOR of unordered pairwise sum –
=> (1 + 2) ^ (1 + 3) ^ (2 + 3)
=> 3 ^ 4 ^ 5
=> 2
Naive Approach: The idea is to find every possible unordered pair with the help of the two loops and find the XOR of these pairs.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int xorOfSum( int a[], int n)
{
int answer = 0;
for ( int i = 0; i < n; i++) {
for ( int j = i + 1; j < n; j++)
answer ^= (a[i] + a[j]);
}
return answer;
}
int main()
{
int n = 3;
int A[n] = { 1, 2, 3 };
cout << xorOfSum(A, n);
return 0;
}
|
Java
class GFG{
static int xorOfSum( int a[], int n)
{
int answer = 0 ;
for ( int i = 0 ; i < n; i++) {
for ( int j = i + 1 ; j < n; j++)
answer ^= (a[i] + a[j]);
}
return answer;
}
public static void main(String[] args)
{
int n = 3 ;
int A[] = { 1 , 2 , 3 };
System.out.print(xorOfSum(A, n));
}
}
|
Python3
def xorOfSum(a, n):
answer = 0
for i in range (n):
for j in range (i + 1 , n):
answer ^ = (a[i] + a[j])
return answer
if __name__ = = '__main__' :
n = 3
A = [ 1 , 2 , 3 ]
print (xorOfSum(A, n))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int xorOfSum( int []a, int n)
{
int answer = 0;
for ( int i = 0; i < n; i++) {
for ( int j = i + 1; j < n; j++)
answer ^= (a[i] + a[j]);
}
return answer;
}
public static void Main(String[] args)
{
int n = 3;
int []A = { 1, 2, 3 };
Console.Write(xorOfSum(A, n));
}
}
|
Javascript
<script>
function xorOfSum(a, n)
{
let answer = 0;
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++)
answer ^= (a[i] + a[j]);
}
return answer;
}
let n = 3;
let A = [ 1, 2, 3 ];
document.write(xorOfSum(A, n));
</script>
|
Time complexity: O(n2), where n is the size of the array.
Space complexity: O(1)
Efficient Approach:
- For obtaining Kth bit of the final xor value we see in all the pair-sums, that kth bit of them is set or not. If there are even a number of pairs that have the Kth bit set, then for the Kth bit, their xor is zero else one.
- For finding count of pair sums having Kth bit set, we notice that we can mod all array elements by 2(K+1). This is because X and Y belong to input array and Sum = X + Y. Then X + Y can add up to have their Kth bit set which means Sum >= 2K. It can also be observed that they can have a carryover from addition which makes numbers in the range [2(K+1), 2(K+1) + 2K) have their Kth bit not set. So we only care about the Kth and (K+1)th bit of all the numbers to check the XOR of Kth bit.
- After the mod operation is performed, for sum to have kth bit set, its value will be in range – [2K, 2(K+1) ) U [2(K+1) + 2K, Max-Value-Sum-Can-Take ].
- To find the numbers in the said range, make another array B containing modded array elements of arr[], and sort them. Then Sum can be assumed as Sum = Bi + Bj. Finally, find the maximum bound of j using binary search (built-in lower_bound in C++). Fix i and since the array is sorted find the last j that satisfies the given condition and all the numbers in the range of indices can be added to the count to check the xor.
Auxiliary Space: O(1)
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int xorOfSum( int a[], int n)
{
int i, j, k;
sort(a, a + n);
int ans = 0;
for (k = 0; k < 27; ++k) {
vector< int > b(n);
for (i = 0; i < n; i++)
b[i] = a[i] % (1 << (k + 1));
sort(b.begin(), b.end());
int cnt = 0;
for (i = 0; i < n; i++) {
int l = lower_bound(b.begin() +
i + 1, b.end(),
(1 << k) - b[i]) - b.begin();
int r = lower_bound(b.begin() +
i + 1, b.end(), (1 << (k + 1)) -
b[i]) - b.begin();
cnt += r - l;
l = lower_bound(b.begin() + i + 1,
b.end(), (1 << (k + 1)) +
(1 << k) - b[i]) - b.begin();
cnt += n - l;
}
ans += (cnt % 2) * 1LL * (1 << k);
}
return ans;
}
int main()
{
int n = 3;
int A[n] = { 1, 2, 3 };
cout << xorOfSum(A, n);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int lower_bound( int [] array, int startIndex,
int element)
{
for ( int i = startIndex; i < array.length; i++) {
if (array[i] >= element) {
return i;
}
}
return array.length;
}
static int xorOfSum( int [] a, int n)
{
Arrays.sort(a);
int ans = 0 ;
for ( int k = 0 ; k < 27 ; k++) {
int [] b = new int [n];
for ( int i = 0 ; i < n; i++) {
b[i] = a[i] % ( 1 << (k + 1 ));
}
Arrays.sort(b);
int cnt = 0 ;
for ( int i = 0 ; i < n; i++) {
int l = lower_bound(b, i + 1 ,
( 1 << k) - b[i]);
int r = lower_bound(b, i + 1 ,
( 1 << (k + 1 )) - b[i]);
cnt += r - l;
l = lower_bound(b, i + 1 ,
( 1 << (k + 1 )) + ( 1 << k)
- b[i]);
cnt += n - l;
}
ans += (cnt % 2 ) * ( 1 << k);
}
return ans;
}
public static void main(String[] args)
{
int n = 3 ;
int [] A = { 1 , 2 , 3 };
System.out.println(xorOfSum(A, n));
}
}
|
Python3
def lower_bound(arr, startIndex, element):
n = len (arr)
for i in range (startIndex, n):
if (arr[i] > = element):
return i
return n
def xorOfSum(a, n):
a.sort()
ans = 0
for k in range ( 27 ):
b = [ 0 for _ in range (n)]
for i in range (n):
b[i] = a[i] % ( 1 << (k + 1 ))
b.sort()
cnt = 0
for i in range (n):
l = lower_bound(b, i + 1 , ( 1 << k) - b[i])
r = lower_bound(b, i + 1 , ( 1 << (k + 1 )) - b[i])
cnt + = r - l
l = lower_bound(b, i + 1 , ( 1 << (k + 1 )) +
( 1 << k) - b[i])
cnt + = n - l
ans + = (cnt % 2 ) * ( 1 << k)
return ans
n = 3
A = [ 1 , 2 , 3 ]
print (xorOfSum(A, n))
|
C#
using System;
public class GFG {
static int lower_bound( int [] array, int startIndex,
int element)
{
for ( int i = startIndex; i < array.Length; i++) {
if (array[i] >= element) {
return i;
}
}
return array.Length;
}
static int xorOfSum( int [] a, int n)
{
Array.Sort(a);
int ans = 0;
for ( int k = 0; k < 27; k++) {
int [] b = new int [n];
for ( int i = 0; i < n; i++) {
b[i] = a[i] % (1 << (k + 1));
}
Array.Sort(b);
int cnt = 0;
for ( int i = 0; i < n; i++) {
int l = lower_bound(b, i + 1,
(1 << k) - b[i]);
int r = lower_bound(b, i + 1,
(1 << (k + 1)) - b[i]);
cnt += r - l;
l = lower_bound(b, i + 1,
(1 << (k + 1)) + (1 << k)
- b[i]);
cnt += n - l;
}
ans += (cnt % 2) * (1 << k);
}
return ans;
}
static public void Main()
{
int n = 3;
int [] A = { 1, 2, 3 };
Console.WriteLine(xorOfSum(A, n));
}
}
|
Javascript
function lower_bound(array, startIndex, element)
{
var n = array.length;
for ( var i = startIndex; i < n; i++)
{
if (array[i] >= element)
return i;
}
return n;
}
function xorOfSum(a, n)
{
var i;
var j;
var k;
a.sort();
var ans = 0;
for (k = 0; k < 27; k++) {
b = new Array(n);
for (i = 0; i < n; i++)
b[i] = a[i] % (1 << (k + 1));
b.sort();
var cnt = 0;
for (i = 0; i < n; i++)
{
var l = lower_bound(b, i + 1, (1 << k) - b[i]);
var r = lower_bound(b,i + 1, (1 << (k + 1)) - b[i]);
cnt += r - l;
l = lower_bound(b, i + 1, (1 << (k + 1)) +
(1 << k) - b[i]);
cnt += n - l;
}
ans += (cnt % 2) * (1 << k);
}
return ans;
}
var n = 3;
var A = [ 1, 2, 3 ];
console.log(xorOfSum(A, n));
|
Performance Analysis:
- Time complexity : O(N * log(max(A))*log(N)
- Auxiliary Space: O(N)
Outermost loop runs for log(max(A)) times and for each loop we create and sort array b ,which consists of N elements ,hence complexity is O(N*log(N)*log(max(A)))
Last Updated :
08 May, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...