Open In App

Compute AND value by doing XOR of given arrays

Given two arrays A[] and B[], the array C[] is formed by the XOR of ai and bi, i.e ci = ai^bi, the task is to find the maximum AND value of all the array elements of C given that A and B can be permuted in any way.

Examples:



Input: A[] ={1, 0, 0, 3, 3}, B[] =  {2, 3, 2, 1, 0}
Output: 2
Explanation:  C [] = {3, 3, 2, 2, 3}  on doing AND of array C value of AND is (3 & 3 & 2 & 2 & 3) = 2 which is the maximum possible AND value considering any permutations of A and B arrays.

Input: A[] = {1, 1, 1}, B[] = {0, 0, 3}
Output:
Explanation: C[] = {1, 1, 2} on doing AND of array C value of AND is (1&1&2) = 0 which is the maximum possible AND value considering any permutations of A and B arrays.



Approach: To solve the problem follow the below idea:

The approach is Greedy where we check from setting the bit from the MSB in the result would result in any permutation of A and B such that, that bit is set in all elements of  C i.e C[i] = A[i] ^ B[i] is set or A[i] & ~B[i], to make bit set in result which is the final AND all the Ci should have that set bit so we check if there is a possibility to have that ith bit set if it is possible we set that bit in the result else not.
The main point is A and B should have matched opposite values so that A[i] ^ B[i] is 1 if A[i] as the kth bit set then there should be a number in B where kth bit is unset.

Follow these steps to solve the above problem:

Below is the implementation of the above approach:




// C++ code for the above approach
#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
 
// Function to check if it is possible to
// obtain 'res' by performing the AND
// operation on all possible pairs of
// elements from 'A' and 'B'
bool check(ll res, ll A[], ll B[], ll n)
{
 
    // Vectors to store the results of the
    // AND operation between 'res' and
    // each element of 'A', and between
    // 'res' and the negation of each
    // element of 'B', respectively
    vector<ll> v1, v2;
 
    // Populate vectors v1 and v2
    for (ll i = 0; i < n; i++) {
        v1.push_back(res & A[i]);
        v2.push_back(res & ~B[i]);
    }
 
    // Sort v1 and v2 in ascending order
    sort(v1.begin(), v1.end());
    sort(v2.begin(), v2.end());
 
    // Check if there are equal number
    // of 0, 1 pairs
    for (ll i = 0; i < n; i++) {
 
        // If any pair of elements from
        // the same indices in v1 and v2
        // are not equal, return false
        if (v1[i] != v2[i]) {
            return false;
        }
    }
 
    // If all pairs of elements from
    // v1 and v2 are equal, return true
    return true;
}
 
// Function to find the maximum AND value
ll find_max_and(ll A[], ll B[], ll n)
{
 
    // Initialize 'res' to 0
    ll res = 0;
 
    // Iterate from the most significant
    // bit (29) to the least
    // significant bit (0)
    for (ll i = 29; i >= 0; i--) {
 
        // Check if it is possible to
        // obtain any permutations of A
        // and B such that ith bit is set
        // in all the elements of C[i]
        if (check(res | (1 << i), A, B, n)) {
 
            // Set the ith bit in the res
            res = (res | (1 << i));
        }
    }
    return res;
}
 
// Driver Code
int main()
{
 
    // Arrays A and B
    ll A[] = { 1, 0, 0, 3, 3 };
    ll B[] = { 2, 3, 2, 1, 0 };
 
    // Size of A and B
    ll n = sizeof(A) / sizeof(A[0]);
 
    // Print 'res'
    cout << find_max_and(A, B, n) << "\n";
 
    ll A2[] = { 1, 1, 1 };
    ll B2[] = { 0, 0, 3 };
 
    // Size of A and B
    ll n2 = sizeof(A2) / sizeof(A2[0]);
 
    // Print 'res'
    cout << find_max_and(A2, B2, n2) << "\n";
 
    return 0;
}




// Java code for the above approach
import java.util.*;
 
public class Main {
 
    // Function to check if it is possible to obtain 'res' by performing
    // the AND operation on all possible pairs of elements from 'A' and 'B'
    static boolean check(long res, long[] A, long[] B, long n) {
 
        // Lists to store the results of the AND operation between 'res' and
        // each element of 'A', and between 'res' and the negation of each
        // element of 'B', respectively
        List<Long> v1 = new ArrayList<>();
        List<Long> v2 = new ArrayList<>();
 
        // Populate lists v1 and v2
        for (long i = 0; i < n; i++) {
            v1.add(res & A[(int) i]);
            v2.add(res & ~B[(int) i]);
        }
 
        // Sort v1 and v2 in ascending order
        Collections.sort(v1);
        Collections.sort(v2);
 
        // Check if there are equal number of 0, 1 pairs
        for (long i = 0; i < n; i++) {
 
            // If any pair of elements from the same indices in v1 and v2
            // are not equal, return false
            if (!Objects.equals(v1.get((int) i), v2.get((int) i))) {
                return false;
            }
        }
 
        // If all pairs of elements from v1 and v2 are equal, return true
        return true;
    }
 
    // Function to find the maximum AND value
    static long findMaxAnd(long[] A, long[] B, long n) {
 
        // Initialize 'res' to 0
        long res = 0;
 
        // Iterate from the most significant bit (29) to the least
        // significant bit (0)
        for (long i = 29; i >= 0; i--) {
 
            // Check if it is possible to obtain any permutations of A
            // and B such that ith bit is set in all the elements of C[i]
            if (check(res | (1 << i), A, B, n)) {
 
                // Set the ith bit in the res
                res = res | (1 << i);
            }
        }
        return res;
    }
 
    public static void main(String[] args) {
 
        // Arrays A and B
        long[] A = {1, 0, 0, 3, 3};
        long[] B = {2, 3, 2, 1, 0};
 
        // Size of A and B
        long n = A.length;
 
        // Print 'res'
        System.out.println(findMaxAnd(A, B, n));
 
        long[] A2 = {1, 1, 1};
        long[] B2 = {0, 0, 3};
 
        // Size of A and B
        long n2 = A2.length;
 
        // Print 'res'
        System.out.println(findMaxAnd(A2, B2, n2));
    }
}




# Python code for the equivalent approach
 
# Function to check if it is possible to
# obtain 'res' by performing the AND
# operation on all possible pairs of
# elements from 'A' and 'B'
def check(res, A, B, n):
      # Vectors to store the results of the
    # AND operation between 'res' and
    # each element of 'A', and between
    # 'res' and the negation of each
    # element of 'B', respectively
    v1, v2 = [], []
     
    # Populate vectors v1 and v2
    for i in range(n):
        v1.append(res & A[i])
        v2.append(res & (~B[i]))
         
    # Sort v1 and v2 in ascending order
    v1.sort()
    v2.sort()
     
    # Check if there are equal number
    # of 0, 1 pairs
    for i in range(n):
       
          # If any pair of elements from
        # the same indices in v1 and v2
        # are not equal, return false
        if v1[i] != v2[i]:
            return False
    # If all pairs of elements from
    # v1 and v2 are equal, return true
    return True
 
# Function to find the maximum AND value
def find_max_and(A, B, n):
      # Initialize 'res' to 0
    res = 0
     
    # Iterate from the most significant
    # bit (29) to the least
    # significant bit (0)
    for i in range(29, -1, -1):
       
          # Check if it is possible to
        # obtain any permutations of A
        # and B such that ith bit is set
        # in all the elements of C[i]
        if check(res | (1 << i), A, B, n):
               
            # Set the ith bit in the res
            res = res | (1 << i)
    return res
 
 
# Arrays A and B
A = [1, 0, 0, 3, 3]
B = [2, 3, 2, 1, 0]
 
# Size of A and B
n = len(A)
 
# Print 'res'
print(find_max_and(A, B, n))
 
A2 = [1, 1, 1]
B2 = [0, 0, 3]
 
# Size of A and B
n2 = len(A2)
 
# Print 'res'
print(find_max_and(A2, B2, n2))
 
# This code is contributed by lokeshmvs21.




// Javascript code for the above approach
 
// Function to check if it is possible to
// obtain 'res' by performing the AND
// operation on all possible pairs of
// elements from 'A' and 'B'
function check(res, A, B, n)
{
 
    // Vectors to store the results of the
    // AND operation between 'res' and
    // each element of 'A', and between
    // 'res' and the negation of each
    // element of 'B', respectively
    let v1=new Array(), v2=new Array();
 
    // Populate vectors v1 and v2
    for (let i = 0; i < n; i++) {
        v1.push(res & A[i]);
        v2.push(res & ~B[i]);
    }
 
    // Sort v1 and v2 in ascending order
    v1.sort();
    v2.sort();
 
    // Check if there are equal number
    // of 0, 1 pairs
    for (let i = 0; i < n; i++) {
 
        // If any pair of elements from
        // the same indices in v1 and v2
        // are not equal, return false
        if (v1[i] != v2[i]) {
            return false;
        }
    }
 
    // If all pairs of elements from
    // v1 and v2 are equal, return true
    return true;
}
 
// Function to find the maximum AND value
function find_max_and( A,  B,  n)
{
 
    // Initialize 'res' to 0
    let res = 0;
 
    // Iterate from the most significant
    // bit (29) to the least
    // significant bit (0)
    for (let i = 29; i >= 0; i--) {
 
        // Check if it is possible to
        // obtain any permutations of A
        // and B such that ith bit is set
        // in all the elements of C[i]
        if (check(res | (1 << i), A, B, n)) {
 
            // Set the ith bit in the res
            res = (res | (1 << i));
        }
    }
    return res;
}
 
// Driver Code
// Arrays A and B
let A =[ 1, 0, 0, 3, 3 ];
let B =[ 2, 3, 2, 1, 0 ];
 
// Size of A and B
let n = A.length;
 
// Print 'res'
console.log(find_max_and(A, B, n));
 
let A2 = [ 1, 1, 1 ];
let B2 = [ 0, 0, 3 ];
 
// Size of A and B
let n2 = A2.length;
 
// Print 'res'
console.log(find_max_and(A2, B2, n2));




// C# code for the above approach
using System;
using System.Collections.Generic;
 
class MainClass {
    // Function to check if it is possible to
    // obtain 'res' by performing the AND
    // operation on all possible pairs of
    // elements from 'A' and 'B'
    static bool check(int res, int[] A, int[] B, int n) {
        // Vectors to store the results of the
        // AND operation between 'res' and
        // each element of 'A', and between
        // 'res' and the negation of each
        // element of 'B', respectively
        List<int> v1 = new List<int>();
        List<int> v2 = new List<int>();
 
        // Populate vectors v1 and v2
        for (int i = 0; i < n; i++) {
            v1.Add(res & A[i]);
            v2.Add(res & (~B[i]));
        }
 
        // Sort v1 and v2 in ascending order
        v1.Sort();
        v2.Sort();
 
        // Check if there are equal number
        // of 0, 1 pairs
        for (int i = 0; i < n; i++) {
 
            // If any pair of elements from
            // the same indices in v1 and v2
            // are not equal, return false
            if (v1[i] != v2[i]) {
                return false;
            }
        }
        // If all pairs of elements from
        // v1 and v2 are equal, return true
        return true;
    }
 
    // Function to find the maximum AND value
    static int find_max_and(int[] A, int[] B, int n) {
        // Initialize 'res' to 0
        int res = 0;
 
        // Iterate from the most significant
        // bit (29) to the least
        // significant bit (0)
        for (int i = 29; i >= 0; i--) {
 
            // Check if it is possible to
            // obtain any permutations of A
            // and B such that ith bit is set
            // in all the elements of C[i]
            if (check(res | (1 << i), A, B, n)) {
 
                // Set the ith bit in the res
                res = res | (1 << i);
            }
        }
        return res;
    }
 
    public static void Main() {
        // Arrays A and B
        int[] A = { 1, 0, 0, 3, 3 };
        int[] B = { 2, 3, 2, 1, 0 };
 
        // Size of A and B
        int n = A.Length;
 
        // Print 'res'
        Console.WriteLine(find_max_and(A, B, n));
 
        int[] A2 = { 1, 1, 1 };
        int[] B2 = { 0, 0, 3 };
 
        // Size of A and B
        int n2 = A2.Length;
 
        // Print 'res'
        Console.WriteLine(find_max_and(A2, B2, n2));
    }
}
// This code is contributed by shivamsharma215.

Output
2
0

Time Complexity: O(NlogN), where N is the size of the array
Auxiliary Space: O(N)

Related Articles:


Article Tags :