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++
#include <bits/stdc++.h>
using namespace std;
#define MAX 2147483647
int one[100001][32];
void make_prefix( int A[], int n)
{
for ( int j = 0; j < 32; j++)
one[0][j] = 0;
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 (a & x)
one[i][j] = 1 + one[i - 1][j];
else
one[i][j] = one[i - 1][j];
}
}
}
int Solve( int L, int R)
{
int l = L, r = R;
int tot_bits = r - l + 1;
int X = MAX;
for ( int i = 0; i < 31; i++)
{
int x = one[r][i] - one[l - 1][i];
if (x >= tot_bits - x)
{
int ith_bit = pow (2, i);
X = X ^ ith_bit;
}
}
return X;
}
int main()
{
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
import java.lang.Math;
class GFG {
private static final int MAX = 2147483647 ;
static int [][] one = new int [ 100001 ][ 32 ];
static void make_prefix( int A[], int n)
{
for ( int j = 0 ; j < 32 ; j++)
one[ 0 ][j] = 0 ;
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 ((a & x) != 0 )
one[i][j] = 1 + one[i - 1 ][j];
else
one[i][j] = one[i - 1 ][j];
}
}
}
static int Solve( int L, int R)
{
int l = L, r = R;
int tot_bits = r - l + 1 ;
int X = MAX;
for ( int i = 0 ; i < 31 ; i++)
{
int x = one[r][i] - one[l - 1 ][i];
if (x >= tot_bits - x)
{
int ith_bit = ( int )Math.pow( 2 , i);
X = X ^ ith_bit;
}
}
return X;
}
public static void main(String[] args)
{
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]));
}
}
|
Python3
import math
one = [[ 0 for x in range ( 32 )]
for y in range ( 100001 )]
MAX = 2147483647
def make_prefix(A, n) :
global one, MAX
for j in range ( 0 , 32 ) :
one[ 0 ][j] = 0
for i in range ( 1 , n + 1 ) :
a = A[i - 1 ]
for j in range ( 0 , 32 ) :
x = int (math. pow ( 2 , j))
if (a & x) :
one[i][j] = 1 + one[i - 1 ][j]
else :
one[i][j] = one[i - 1 ][j]
def Solve(L, R) :
global one, MAX
l = L
r = R
tot_bits = r - l + 1
X = MAX
for i in range ( 0 , 31 ) :
x = one[r][i] - one[l - 1 ][i]
if (x > = (tot_bits - x)) :
ith_bit = pow ( 2 , i)
X = X ^ ith_bit
return X
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" )
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int MAX = 2147483647;
static int [,]one = new int [100001,32];
static void make_prefix( int []A, int n)
{
for ( int j = 0; j < 32; j++)
one[0,j] = 0;
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 ((a & x) != 0)
one[i, j] = 1 + one[i - 1, j];
else
one[i,j] = one[i - 1, j];
}
}
}
static int Solve( int L, int R)
{
int l = L, r = R;
int tot_bits = r - l + 1;
int X = MAX;
for ( int i = 0; i < 31; i++)
{
int x = one[r, i] - one[l - 1, i];
if (x >= tot_bits - x)
{
int ith_bit = ( int )Math.Pow(2, i);
X = X ^ ith_bit;
}
}
return X;
}
public static void Main()
{
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]));
}
}
|
PHP
<?php
error_reporting (0);
$one = array ();
$MAX = 2147483647;
function make_prefix( $A , $n )
{
global $one , $MAX ;
for ( $j = 0; $j < 32; $j ++)
$one [0][ $j ] = 0;
for ( $i = 1; $i <= $n ; $i ++)
{
$a = $A [ $i - 1];
for ( $j = 0; $j < 32; $j ++)
{
$x = pow(2, $j );
if ( $a & $x )
$one [ $i ][ $j ] = 1 + $one [ $i - 1][ $j ];
else
$one [ $i ][ $j ] = $one [ $i - 1][ $j ];
}
}
}
function Solve( $L , $R )
{
global $one , $MAX ;
$l = $L ; $r = $R ;
$tot_bits = $r - $l + 1;
$X = $MAX ;
for ( $i = 0; $i < 31; $i ++)
{
$x = $one [ $r ][ $i ] - $one [ $l - 1][ $i ];
if ( $x >= ( $tot_bits - $x ))
{
$ith_bit = pow(2, $i );
$X = $X ^ $ith_bit ;
}
}
return $X ;
}
$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" );
?>
|
Javascript
<script>
const MAX = 2147483647;
let one = new Array(100001);
for (let i = 0; i < 100001; i++)
one[i] = new Array(32);
function make_prefix(A, n)
{
for (let j = 0; j < 32; j++)
one[0][j] = 0;
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 (a & x)
one[i][j] = 1 + one[i - 1][j];
else
one[i][j] = one[i - 1][j];
}
}
}
function Solve(L, R)
{
let l = L, r = R;
let tot_bits = r - l + 1;
let X = MAX;
for (let i = 0; i < 31; i++)
{
let x = one[r][i] - one[l - 1][i];
if (x >= tot_bits - x)
{
let ith_bit = Math.pow(2, i);
X = X ^ ith_bit;
}
}
return X;
}
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++
#include <bits/stdc++.h>
using namespace std;
#define MAX 2147483647
int prefixSum[100001];
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];
}
int Solve( int A[], int L, int R)
{
int n = prefixSum[R] - prefixSum[L] + A[L];
return MAX - n;
}
int main()
{
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
import java.util.*;
class GFG
{
static int MAX = 2147483647 ;
static int [] prefixSum;
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];
}
static int Solve( int A[], int L, int R)
{
int n = prefixSum[R] - prefixSum[L] + A[L];
return MAX - n;
}
public static void main(String[] args)
{
prefixSum = new int [ 100001 ];
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]));
}
}
|
Python
MAX = 2147483647
prefixSum = [ 0 ] * 100001
def make_prefix(A, n):
global prefixSum
prefixSum[ 0 ] = A[ 0 ]
for i in range ( 1 , n):
prefixSum[i] = prefixSum[i - 1 ] + A[i]
def Solve(A, L, R):
global MAX , prefixSum
n = prefixSum[R] - prefixSum[L] + A[L]
return MAX - n
if __name__ = = "__main__" :
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]))
|
C#
using System;
class GFG {
static int MAX = 2147483647;
static int [] prefixSum;
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];
}
static int Solve( int [] A, int L, int R)
{
int n = prefixSum[R] - prefixSum[L] + A[L];
return MAX - n;
}
public static void Main( string [] args)
{
prefixSum = new int [100001];
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]));
}
}
|
Javascript
let prefixSum = [];
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 Solve(A, L, R)
{
let n = prefixSum[R] - prefixSum[L] + A[L];
let MAX = 2147483647;
return MAX - n;
}
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]));
|
Time complexity: O(n)
Auxiliary Space: O(n)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
23 Feb, 2023
Like Article
Save Article