Open In App

Number whose sum of XOR with given array range is maximum

Improve
Improve
Like Article
Like
Save
Share
Report

You are given a sequence of N integers and Q queries. In each query, you are given two parameters L and R. You have to find the smallest integer X such that 0 <= X < 2^31 and the sum of XOR of x with all elements in range [L, R] is maximum possible.
Examples : 
 

Input  : A = {20, 11, 18, 2, 13}
         Three queries as (L, R) pairs
         1 3
         3 5
         2 4
Output : 2147483629
         2147483645
         2147483645

 

Approach: The binary representation of each element and X, we can observe that each bit is independent and the problem can be solved by iterating over each bit. Now basically for each bit we need to count the number of 1’s and 0’s in the given range, if the number of 1’s are more then you have to set that bit of X to 0 so that the sum is maximum after xor with X else if number of 0’s are more then you have to set that bit of X to 1. If the number of 1’s and 0’s are equal then we can set that bit of X to any one of 1 or 0 because it will not affect the sum, but we have to minimize the value of X so we will take that bit 0.
Now, to optimize the solution we can pre-calculate the count of 1’s at each bit position of the numbers up to that position by making a prefix array this will take O(n) time. Now for each query number of 1’s will be the number of 1’s up to Rth position – number of 1’s up to (L-1)th position.
 

C++




// CPP program to find smallest integer X
// such that sum of its XOR with range is
// maximum.
#include <bits/stdc++.h>
using namespace std;
 
#define MAX 2147483647
int one[100001][32];
 
// Function to make prefix array which
// counts 1's of each bit up to that number
void make_prefix(int A[], int n)
{
    for (int j = 0; j < 32; j++)
        one[0][j] = 0;
 
    // Making a prefix array which sums
    // number of 1's up to that position
    for (int i = 1; i <= n; i++)
    {
        int a = A[i - 1];
        for (int j = 0; j < 32; j++)
        {
            int x = pow(2, j);
 
            // If j-th bit of a number is set then
            // add one to previously counted 1's
            if (a & x)
                one[i][j] = 1 + one[i - 1][j];
            else
                one[i][j] = one[i - 1][j];
        }
    }
}
 
// Function to find X
int Solve(int L, int R)
{
    int l = L, r = R;
    int tot_bits = r - l + 1;
 
    // Initially taking maximum value all bits 1
    int X = MAX;
 
    // Iterating over each bit
    for (int i = 0; i < 31; i++)
    {
 
        // get 1's at ith bit between the
        // range L-R by subtracting 1's till
        // Rth number - 1's till L-1th number
        int x = one[r][i] - one[l - 1][i];
 
        // If 1's are more than or equal to 0's
        // then unset the ith bit from answer
        if (x >= tot_bits - x)
        {
            int ith_bit = pow(2, i);
 
            // Set ith bit to 0 by doing
            // Xor with 1
            X = X ^ ith_bit;
        }
    }
    return X;
}
 
// Driver program
int main()
{
    // Taking inputs
    int n = 5, q = 3;
    int A[] = { 210, 11, 48, 22, 133 };
    int L[] = { 1, 4, 2 }, R[] = { 3, 14, 4 };
 
    make_prefix(A, n);
 
    for (int j = 0; j < q; j++)
        cout << Solve(L[j], R[j]) << endl;
 
    return 0;
}


Java




// Java program to find smallest integer X
// such that sum of its XOR with range is
// maximum.
import java.lang.Math;
 
class GFG {
     
    private static final int MAX = 2147483647;
    static int[][] one = new int[100001][32];
     
    // Function to make prefix array which counts
    // 1's of each bit up to that number
    static void make_prefix(int A[], int n)
    {
        for (int j = 0; j < 32; j++)
            one[0][j] = 0;
 
        // Making a prefix array which sums
        // number of 1's up to that position
        for (int i = 1; i <= n; i++)
        {
            int a = A[i - 1];
            for (int j = 0; j < 32; j++)
            {
                int x = (int)Math.pow(2, j);
 
                // If j-th bit of a number is set then
                // add one to previously counted 1's
                if ((a & x) != 0)
                    one[i][j] = 1 + one[i - 1][j];
                else
                    one[i][j] = one[i - 1][j];
            }
        }
    }
 
    // Function to find X
    static int Solve(int L, int R)
    {
        int l = L, r = R;
        int tot_bits = r - l + 1;
 
        // Initially taking maximum
        // value all bits 1
        int X = MAX;
 
        // Iterating over each bit
        for (int i = 0; i < 31; i++)
        {
 
            // get 1's at ith bit between the range
            // L-R by subtracting 1's till
            // Rth number - 1's till L-1th number
            int x = one[r][i] - one[l - 1][i];
 
            // If 1's are more than or equal to 0's
            // then unset the ith bit from answer
            if (x >= tot_bits - x)
            {
                int ith_bit = (int)Math.pow(2, i);
 
                // Set ith bit to 0 by
                // doing Xor with 1
                X = X ^ ith_bit;
            }
        }
        return X;
    }
 
    // Driver program
    public static void main(String[] args)
    {
        // Taking inputs
        int n = 5, q = 3;
        int A[] = { 210, 11, 48, 22, 133 };
        int L[] = { 1, 4, 2 }, R[] = { 3, 14, 4 };
 
        make_prefix(A, n);
 
        for (int j = 0; j < q; j++)
            System.out.println(Solve(L[j], R[j]));
    }
}
 
// This code is contributed by Smitha


Python3




# Python3 program to find smallest integer X
# such that sum of its XOR with range is
# maximum.
import math
 
one = [[0 for x in range(32)]
      for y in range(100001)]
MAX = 2147483647
 
# Function to make prefix array
# which counts 1's of each bit
# up to that number
def make_prefix(A, n) :
    global one, MAX
     
    for j in range(0 , 32) :
        one[0][j] = 0
 
    # Making a prefix array which
    # sums number of 1's up to
    # that position
    for i in range(1, n+1) :
        a = A[i - 1]
        for j in range(0 , 32) :
         
            x = int(math.pow(2, j))
 
            # If j-th bit of a number
            # is set then add one to
            # previously counted 1's
            if (a & x) :
                one[i][j] = 1 + one[i - 1][j]
            else :
                one[i][j] = one[i - 1][j]
         
# Function to find X
def Solve(L, R) :
 
    global one, MAX
    l = L
    r = R
    tot_bits = r - l + 1
 
    # Initially taking maximum
    # value all bits 1
    X = MAX
 
    # Iterating over each bit
    for i in range(0, 31) :
     
        # get 1's at ith bit between the
        # range L-R by subtracting 1's till
        # Rth number - 1's till L-1th number
         
        x = one[r][i] - one[l - 1][i]
 
        # If 1's are more than or equal
        # to 0's then unset the ith bit
        # from answer
        if (x >= (tot_bits - x)) :
             
            ith_bit = pow(2, i)
 
            # Set ith bit to 0 by
            # doing Xor with 1
            X = X ^ ith_bit
    return X
 
# Driver Code
n = 5
q = 3
A = [ 210, 11, 48, 22, 133 ]
L = [ 1, 4, 2 ]
R = [ 3, 14, 4 ]
 
make_prefix(A, n)
 
for j in range(0, q) :
    print (Solve(L[j], R[j]),end="\n")
     
# This code is contributed by
# Manish Shaw(manishshaw1)


C#




// C# program to find smallest integer X
// such that sum of its XOR with range is
// maximum.
using System;
using System.Collections.Generic;
 
class GFG{
    static int MAX = 2147483647;
    static int [,]one = new int[100001,32];
     
    // Function to make prefix
    // array which counts 1's
    // of each bit up to that number
    static void make_prefix(int []A, int n)
    {
        for (int j = 0; j < 32; j++)
            one[0,j] = 0;
     
        // Making a prefix array which sums
        // number of 1's up to that position
        for (int i = 1; i <= n; i++)
        {
            int a = A[i - 1];
            for (int j = 0; j < 32; j++)
            {
                int x = (int)Math.Pow(2, j);
     
                // If j-th bit of a number is set then
                // add one to previously counted 1's
                if ((a & x) != 0)
                    one[i, j] = 1 + one[i - 1, j];
                else
                    one[i,j] = one[i - 1, j];
            }
        }
    }
     
    // Function to find X
    static int Solve(int L, int R)
    {
        int l = L, r = R;
        int tot_bits = r - l + 1;
     
        // Initially taking maximum
        // value all bits 1
        int X = MAX;
     
        // Iterating over each bit
        for (int i = 0; i < 31; i++)
        {
     
            // get 1's at ith bit between the
            // range L-R by subtracting 1's till
            // Rth number - 1's till L-1th number
            int x = one[r, i] - one[l - 1, i];
     
            // If 1's are more than or
            // equal to 0's then unset
            // the ith bit from answer
            if (x >= tot_bits - x)
            {
                int ith_bit = (int)Math.Pow(2, i);
     
                // Set ith bit to 0 by doing
                // Xor with 1
                X = X ^ ith_bit;
            }
        }
        return X;
    }
     
    // Driver Code
    public static void Main()
    {
         
        // Taking inputs
        int n = 5, q = 3;
        int []A = {210, 11, 48, 22, 133};
        int []L = {1, 4, 2};
        int []R = {3, 14, 4};
     
        make_prefix(A, n);
     
        for (int j = 0; j < q; j++)
            Console.WriteLine(Solve(L[j], R[j]));
    }
}
 
// This code is contributed by
// Manish Shaw (manishshaw1)


PHP




<?php
error_reporting(0);
// PHP program to find smallest integer X
// such that sum of its XOR with range is
// maximum.
 
$one = array();
$MAX = 2147483647;
 
// Function to make prefix array
// which counts 1's of each bit
// up to that number
function make_prefix($A, $n)
{
    global $one, $MAX;
     
    for ($j = 0; $j < 32; $j++)
        $one[0][$j] = 0;
 
    // Making a prefix array which
    // sums number of 1's up to
    // that position
    for ($i = 1; $i <= $n; $i++)
    {
        $a = $A[$i - 1];
        for ($j = 0; $j < 32; $j++)
        {
            $x = pow(2, $j);
 
            // If j-th bit of a number
            // is set then add one to
            // previously counted 1's
            if ($a & $x)
                $one[$i][$j] = 1 + $one[$i - 1][$j];
            else
                $one[$i][$j] = $one[$i - 1][$j];
        }
    }
}
 
// Function to find X
function Solve($L, $R)
{
    global $one, $MAX;
    $l = $L; $r = $R;
    $tot_bits = $r - $l + 1;
 
    // Initially taking maximum
    // value all bits 1
    $X = $MAX;
 
    // Iterating over each bit
    for ($i = 0; $i < 31; $i++)
    {
        // get 1's at ith bit between the
        // range L-R by subtracting 1's till
        // Rth number - 1's till L-1th number
         
        $x = $one[$r][$i] - $one[$l - 1][$i];
 
        // If 1's are more than or equal
        // to 0's then unset the ith bit
        // from answer
        if ($x >= ($tot_bits - $x))
        {
            $ith_bit = pow(2, $i);
 
            // Set ith bit to 0 by
            // doing Xor with 1
            $X = $X ^ $ith_bit;
        }
    }
    return $X;
}
 
// Driver Code
$n = 5; $q = 3;
$A = [ 210, 11, 48, 22, 133 ];
$L = [ 1, 4, 2 ];
$R = [ 3, 14, 4 ];
 
make_prefix($A, $n);
 
for ($j = 0; $j < $q; $j++)
    echo (Solve($L[$j], $R[$j]). "\n");
     
// This code is contributed by
// Manish Shaw(manishshaw1)
?>


Javascript




<script>
// Javascript program to find smallest integer X
// such that sum of its XOR with range is
// maximum.
 
const MAX = 2147483647;
let one = new Array(100001);
for (let i = 0; i < 100001; i++)
    one[i] = new Array(32);
 
// Function to make prefix array which
// counts 1's of each bit up to that number
function make_prefix(A, n)
{
    for (let j = 0; j < 32; j++)
        one[0][j] = 0;
 
    // Making a prefix array which sums
    // number of 1's up to that position
    for (let i = 1; i <= n; i++)
    {
        let a = A[i - 1];
        for (let j = 0; j < 32; j++)
        {
            let x = Math.pow(2, j);
 
            // If j-th bit of a number is set then
            // add one to previously counted 1's
            if (a & x)
                one[i][j] = 1 + one[i - 1][j];
            else
                one[i][j] = one[i - 1][j];
        }
    }
}
 
// Function to find X
function Solve(L, R)
{
    let l = L, r = R;
    let tot_bits = r - l + 1;
 
    // Initially taking maximum value all bits 1
    let X = MAX;
 
    // Iterating over each bit
    for (let i = 0; i < 31; i++)
    {
 
        // get 1's at ith bit between the
        // range L-R by subtracting 1's till
        // Rth number - 1's till L-1th number
        let x = one[r][i] - one[l - 1][i];
 
        // If 1's are more than or equal to 0's
        // then unset the ith bit from answer
        if (x >= tot_bits - x)
        {
            let ith_bit = Math.pow(2, i);
 
            // Set ith bit to 0 by doing
            // Xor with 1
            X = X ^ ith_bit;
        }
    }
    return X;
}
 
// Driver program
    // Taking inputs
    let n = 5, q = 3;
    let A = [ 210, 11, 48, 22, 133 ];
    let L = [ 1, 4, 2 ], R = [ 3, 14, 4 ];
 
    make_prefix(A, n);
 
    for (let j = 0; j < q; j++)
        document.write(Solve(L[j], R[j]) + "<br>");
 
</script>


Output : 
 

2147483629
2147483647
2147483629

Time complexity: O(n)

Auxiliary Space: O(n)

Approach 2 :

From the below table you can see that if we are given a number n, our answer would “N-n”, where N is all 1s.
And we can get n (which is sum of all integers from A[i] to A[j])  using “prefixSum[j] – prefixSum[i]”.

Number (n) 1 0 0 1 0 0 1
All 1s (N) 1 1 1 1 1 1 1
N-n 0 1 1 0 1 1 0

C++




// CPP program to find smallest integer X
// such that sum of its XOR with range is
// maximum.
#include <bits/stdc++.h>
using namespace std;
 
// MAX is (1 << 31) -1 or in other terms 2^31 - 1
#define MAX 2147483647
int prefixSum[100001];
 
// Function to make prefix Sum array which
void make_prefix(int A[], int n)
{
    prefixSum[0] = A[0];
    for (int i = 1; i < n; i++)
        prefixSum[i] = prefixSum[i - 1] + A[i];
}
 
// Function to find X
int Solve(int A[], int L, int R)
{
   
   
    int n = prefixSum[R] - prefixSum[L] + A[L];
    return MAX - n;
}
 
// Driver program
int main()
{
    // Taking inputs
    int n = 5, q = 3;
    int A[] = { 210, 11, 48, 22, 133 };
    int L[] = { 1, 4, 2 }, R[] = { 3, 4, 4 };
 
    make_prefix(A, n);
 
    for (int j = 0; j < q; j++)
        cout << Solve(A, L[j], R[j]) << endl;
 
    return 0;
}


Java




// Java program to find smallest integer X
// such that sum of its XOR with range is
// maximum.
import java.util.*;
 
class GFG
{
   
  // MAX is (1 << 31) -1 or in other terms 2^31 - 1
  static int MAX = 2147483647;
  static int[] prefixSum;
 
  // Function to make prefix Sum array which
  static void make_prefix(int A[], int n)
  {
    prefixSum[0] = A[0];
    for (int i = 1; i < n; i++)
      prefixSum[i] = prefixSum[i - 1] + A[i];
  }
 
  // Function to find X
  static int Solve(int A[], int L, int R)
  {
 
    int n = prefixSum[R] - prefixSum[L] + A[L];
    return MAX - n;
  }
 
  // Driver program
  public static void main(String[] args)
  {
    prefixSum = new int[100001];
     
    // Taking inputs
    int n = 5, q = 3;
    int A[] = { 210, 11, 48, 22, 133 };
    int L[] = { 1, 4, 2 }, R[] = { 3, 4, 4 };
 
    make_prefix(A, n);
 
    for (int j = 0; j < q; j++)
      System.out.println(Solve(A, L[j], R[j]));
  }
}
 
// This code is contributed by karandeep1234


Python




# CPP program to find smallest integer X
# such that sum of its XOR with range is
# maximum.
 
MAX = 2147483647
prefixSum = [0] * 100001
 
# Function to make prefix Sum array which
def make_prefix(A, n):
    global prefixSum
    prefixSum[0] = A[0]
    for i in range(1, n):
        prefixSum[i] = prefixSum[i - 1] + A[i]
 
# Function to find X
def Solve(A, L, R):
    global MAX, prefixSum
    n = prefixSum[R] - prefixSum[L] + A[L]
    return MAX - n
 
# Driver program
if __name__ == "__main__":
    # Taking inputs
    n, q = 5, 3
    A = [210, 11, 48, 22, 133]
    L = [1, 4, 2]
    R = [3, 4, 4]
 
    make_prefix(A, n)
 
    for j in range(q):
        print(Solve(A, L[j], R[j]))
 
# This code is contributed by bhardwajji


C#




// C# program to find smallest integer X
// such that sum of its XOR with range is
// maximum.
using System;
 
class GFG {
 
  // MAX is (1 << 31) -1 or in other terms 2^31 - 1
  static int MAX = 2147483647;
  static int[] prefixSum;
 
  // Function to make prefix Sum array which
  static void make_prefix(int[] A, int n)
  {
    prefixSum[0] = A[0];
    for (int i = 1; i < n; i++)
      prefixSum[i] = prefixSum[i - 1] + A[i];
  }
 
  // Function to find X
  static int Solve(int[] A, int L, int R)
  {
 
    int n = prefixSum[R] - prefixSum[L] + A[L];
    return MAX - n;
  }
 
  // Driver program
  public static void Main(string[] args)
  {
    prefixSum = new int[100001];
 
    // Taking inputs
    int n = 5, q = 3;
    int[] A = { 210, 11, 48, 22, 133 };
    int[] L = { 1, 4, 2 }, R = { 3, 4, 4 };
 
    make_prefix(A, n);
 
    for (int j = 0; j < q; j++)
      Console.WriteLine(Solve(A, L[j], R[j]));
  }
}
 
// This code is contributed by karandeep1234


Javascript




// JAVASCRIPT program to find smallest integer X
// such that sum of its XOR with range is
// maximum.
 
let prefixSum = [];
 
// Function to make prefix Sum array which
function make_prefix(A, n)
{
     
    for(let i = 0; i < n; i++)
    {
        prefixSum.push(0);
    }
    for (let i = 1; i < n; i++)
        prefixSum[i] = prefixSum[i - 1] + A[i];
}
 
// Function to find X
function Solve(A,  L,  R)
{
    let n = prefixSum[R] - prefixSum[L] + A[L];
     
    // MAX is (1 << 31) -1 or in other terms 2^31 - 1
    let MAX = 2147483647;
    return MAX - n;
}
 
// Driver program
 
    // Taking inputs
    let n = 5, q = 3;
    let A = [ 210, 11, 48, 22, 133 ];
    let L = [ 1, 4, 2 ], R = [ 3, 4, 4 ];
 
    make_prefix(A, n);
 
    for (let j = 0; j < q; j++)
        console.log(Solve(A, L[j], R[j]));
 
// This code is contributed by garg28harsh.


Time complexity: O(n)

Auxiliary Space: O(n)
 



Last Updated : 23 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads