Given two integer arrays A[] and B[] of size N and M respectively. Another array C is formed of size N*M, containing Bitwise OR of all possible pairs of elements of A with all elements of B i.e. A[i] | B[j] for all valid i and j. Find the Bitwise XOR of array C i.e. C [0] ^ C[1] ^ …….C[N*M].
Examples:
Input: N = 1, M = 3, A[] = {2}, B[] = {5, 0, 3}
Output: 6
Explanation: (2 OR 5) XOR (2 OR 0) XOR (2 OR 3) = 6.Input: N = 2, M = 2, A[] = {1, 2}, B[] = {4, 10}
Output: 2
Explanation: Array C = [5, 11, 6, 10]. Xor is 2
Bruteforce Approach: The basic way to solve the problem:
The naive approach would be using nested loops to formulate all the possible pairs and find out the array C by evaluating the bitwise OR of every pair. Now calculate the bitwise XOR of the array C, to obtain the results.
Time complexity: O(N*M). where N and M are the lengths of the two arrays.
Efficient approach: To solve the problem follow the below intuition:
We need to check if the ith bit is set or not in the final answer. So for that we will maintain a count array, which will conatins the number of set bits in the array B at ith bit. Now we iterate on array A if the ith bit for a element in array A is a set bit then add M to the value if not add count[i] to the value. finally if the value is odd then the ith bit is set in the final answer.
Steps to solve the problem:
- Keep a track of count array of length 30. Where the ith index in the array i.e., count[i] denotes the number of set bits at ith position in the array B.
-
Now iterate on each bit i, for all the elements in array A do the following:
- If ith bit is set add M i.e, length of array B to the variable value.
- else add count[i] to the variable value.
- If for a particular bit the the value obtained is odd then the bit is set in the final answer.
- Return answer after performing the above step on every bit.
Implementation of the above approach:
// C++ code for the above approach: #include <iostream> using namespace std;
int findORAndXOR( int A[], int B[], int N, int M)
{ // Count array to keep track of set bits
int count[30] = { 0 };
// To store final answer
int ans = 0;
for ( int i = 0; i < 30; i++) {
for ( int j = 0; j < M; j++) {
if (B[j] & (1 << i))
count[i]++;
}
}
for ( int i = 0; i < 30; i++) {
int value = 0;
for ( int j = 0; j < N; j++) {
if (A[j] & (1 << i))
value += M;
else
value += count[i];
}
// if value is odd. The current bit is
// set in the final answer.
if (value & 1)
ans |= (1 << i);
}
return ans;
} // Drivers code int main()
{ int N = 2, M = 2;
int A[N] = { 1, 2 };
int B[M] = { 4, 10 };
// Function Call
cout << findORAndXOR(A, B, N, M);
return 0;
} |
// Java code for the above approach import java.util.Arrays;
class GFG {
public static int findORAndXOR( int [] A, int [] B, int N,
int M)
{
// Count array to keep track of set bits
int [] count = new int [ 30 ];
// To store final answer
int ans = 0 ;
for ( int i = 0 ; i < 30 ; i++) {
for ( int j = 0 ; j < M; j++) {
if ((B[j] & ( 1 << i)) != 0 )
count[i]++;
}
}
for ( int i = 0 ; i < 30 ; i++) {
int value = 0 ;
for ( int j = 0 ; j < N; j++) {
if ((A[j] & ( 1 << i)) != 0 )
value += M;
else
value += count[i];
}
// if value is odd. The current bit is
// set in the final answer.
if ((value & 1 ) != 0 )
ans |= ( 1 << i);
}
return ans;
}
// Driver code
public static void main(String[] args)
{
int N = 2 , M = 2 ;
int [] A = { 1 , 2 };
int [] B = { 4 , 10 };
// Function Call
System.out.println(findORAndXOR(A, B, N, M));
}
} // This code is contributed by Abhinav Mahajan (abhinav_m22) |
def find_OR_and_XOR(A, B):
# Count array to keep track of set bits
count = [ 0 ] * 30
ans = 0
# Counting set bits in array B
for i in range ( 30 ):
for j in range ( len (B)):
if B[j] & ( 1 << i):
count[i] + = 1
# Calculating the final answer bit by bit
for i in range ( 30 ):
value = 0
# Computing the value for each bit position
for j in range ( len (A)):
if A[j] & ( 1 << i):
value + = len (B)
else :
value + = count[i]
# Checking for odd value to set the bit in the final answer
if value & 1 :
ans | = ( 1 << i)
return ans
# Driver code N = 2
M = 2
A = [ 1 , 2 ]
B = [ 4 , 10 ]
# Function Call and printing the result print (find_OR_and_XOR(A, B))
|
using System;
class GFG
{ public static int FindORAndXOR( int [] A, int [] B, int N, int M)
{
// Count array to keep track of set bits
int [] count = new int [30];
// To store final answer
int ans = 0;
for ( int i = 0; i < 30; i++)
{
for ( int j = 0; j < M; j++)
{
if ((B[j] & (1 << i)) != 0)
count[i]++;
}
}
for ( int i = 0; i < 30; i++)
{
int value = 0;
for ( int j = 0; j < N; j++)
{
if ((A[j] & (1 << i)) != 0)
value += M;
else
value += count[i];
}
// if value is odd. The current bit is
// set in the final answer.
if ((value & 1) != 0)
ans |= (1 << i);
}
return ans;
}
// Driver code
public static void Main( string [] args)
{
int N = 2, M = 2;
int [] A = { 1, 2 };
int [] B = { 4, 10 };
// Function Call
Console.WriteLine(FindORAndXOR(A, B, N, M));
}
} |
// Javascript code for the above approach: function findORAndXOR(A, B, N, M) {
// Count array to keep track of set bits
const count = Array(30).fill(0);
// To store final answer
let ans = 0;
for (let i = 0; i < 30; i++) {
for (let j = 0; j < M; j++) {
if (B[j] & (1 << i))
count[i]++;
}
}
for (let i = 0; i < 30; i++) {
let value = 0;
for (let j = 0; j < N; j++) {
if (A[j] & (1 << i))
value += M;
else
value += count[i];
}
// if value is odd. The current bit is
// set in the final answer.
if (value & 1)
ans |= (1 << i);
}
return ans;
} // Drivers code const N = 2, M = 2;
const A = [1, 2]; const B = [4, 10]; // Function Call console.log(findORAndXOR(A, B, N, M)); // This code is contributed by ragul21 |
2
Time Complexity: O(30 * max(N, M)). Where N and M are the lengths of array A and B respectively.
Auxillary Space: O(30). Space used for count array.