XOR of all the elements in the given range [L, R]
Given a range [L, R], the task is to find the XOR of all the integers in the given range i.e. (L) ^ (L + 1) ^ (L + 2) ^ … ^ (R)
Examples:
Input: L = 1, R = 4
Output: 4
1 ^ 2 ^ 3 ^ 4 = 4
Input: L = 3, R = 9
Output: 2
A simple solution is to find XOR of all the numbers iteratively from L to R. This will take linear time.
A better solution is to first find the most significant bit in the integer R. Our answer cannot have it’s a most significant bit larger than that of ‘R’. For each bit ‘i’ between 0 and MSB inclusive, we will try to determine the parity of count of a number of integers between L and R inclusive such that there ‘ith‘ bit is set. If the count is odd, then the ‘ith‘ bit of our final answer will also be set.
Now the real question is, for ith bit, how do we determine the parity of the count?
For an idea, let’s look at the binary representation of the first 16 integers.
0: 0000
1: 0001
2: 0010
3: 0011
4: 0100
5: 0101
6: 0110
7: 0111
8: 1000
9: 1001
10: 1010
11: 1011
12: 1100
13: 1101
14: 1110
15: 1111
It’s easily noticeable that the state of ith bit changes after every 2i number. We will use this idea to predict the count of a number of integers with ith bit set in the range L to R inclusive.
We have two cases here:
- Case 1(i != 0): We try to determine whether the ith bit of L is set or not. If set, we try to find the parity of the count of numbers between L and L + 2i inclusive, such that their ith bit is set. If ith bit of L is set and L is odd, then this count will be odd else even.
Similarly for R, we try to determine the parity of the count of a number of elements between R – 2i and R, such that their ith bit is set. If ith bit of L is set and L is even, then this count will be odd else even.
We ignore all the other integers in between because they will have even number of integers with ith bit set.
- Case 2(i = 0): Here, we have the following cases:
- If L and R, both are odd, the count of the number of integers with 0th bit set will be (R – L)/2 + 1
- In any other case, the count will be floor((R – L + 1)/2).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int msb( int x)
{
int ret = 0;
while ((x >> (ret + 1)) != 0)
ret++;
return ret;
}
int xorRange( int l, int r)
{
int max_bit = msb(r);
int mul = 2;
int ans = 0;
for ( int i = 1; i <= max_bit; i++) {
if ((l / mul) * mul == (r / mul) * mul) {
if (((l & (1 << i)) != 0) && (r - l + 1) % 2 == 1)
ans += mul;
mul *= 2;
continue ;
}
bool odd_c = 0;
if (((l & (1 << i)) != 0) && l % 2 == 1)
odd_c = (odd_c ^ 1);
if (((r & (1 << i)) != 0) && r % 2 == 0)
odd_c = (odd_c ^ 1);
if (odd_c)
ans += mul;
mul *= 2;
}
int zero_bit_cnt = zero_bit_cnt = (r - l + 1) / 2;
if (l % 2 == 1 && r % 2 == 1)
zero_bit_cnt++;
if (zero_bit_cnt % 2 == 1)
ans++;
return ans;
}
int main()
{
int l = 1, r = 4;
cout << xorRange(l, r);
return 0;
}
|
Java
class GFG
{
static int msb( int x)
{
int ret = 0 ;
while ((x >> (ret + 1 )) != 0 )
ret++;
return ret;
}
static int xorRange( int l, int r)
{
int max_bit = msb(r);
int mul = 2 ;
int ans = 0 ;
for ( int i = 1 ; i <= max_bit; i++)
{
if ((l / mul) * mul == (r / mul) * mul)
{
if (((l & ( 1 << i)) != 0 ) && (r - l + 1 ) % 2 == 1 )
ans += mul;
mul *= 2 ;
continue ;
}
int odd_c = 0 ;
if (((l & ( 1 << i)) != 0 ) && l % 2 == 1 )
odd_c = (odd_c ^ 1 );
if (((r & ( 1 << i)) != 0 ) && r % 2 == 0 )
odd_c = (odd_c ^ 1 );
if (odd_c!= 0 )
ans += mul;
mul *= 2 ;
}
int zero_bit_cnt = zero_bit_cnt = (r - l + 1 ) / 2 ;
if (l % 2 == 1 && r % 2 == 1 )
zero_bit_cnt++;
if (zero_bit_cnt % 2 == 1 )
ans++;
return ans;
}
public static void main(String args[])
{
int l = 1 , r = 4 ;
System.out.print(xorRange(l, r));
}
}
|
Python3
def msb(x) :
ret = 0
while ((x >> (ret + 1 )) ! = 0 ) :
ret = ret + 1
return ret
def xorRange(l, r) :
max_bit = msb(r)
mul = 2
ans = 0
for i in range ( 1 , max_bit + 1 ) :
if ((l / / mul) * mul = = (r / / mul) * mul) :
if ((((l & ( 1 << i)) ! = 0 ) and
(r - l + 1 ) % 2 = = 1 )) :
ans = ans + mul
mul = mul * 2
continue
odd_c = 0
if (((l & ( 1 << i)) ! = 0 ) and l % 2 = = 1 ) :
odd_c = (odd_c ^ 1 )
if (((r & ( 1 << i)) ! = 0 ) and r % 2 = = 0 ) :
odd_c = (odd_c ^ 1 )
if (odd_c) :
ans = ans + mul
mul = mul * 2
zero_bit_cnt = (r - l + 1 ) / / 2
if ((l % 2 = = 1 ) and (r % 2 = = 1 )) :
zero_bit_cnt = zero_bit_cnt + 1
if (zero_bit_cnt % 2 = = 1 ):
ans = ans + 1
return ans
l = 1
r = 4
print (xorRange(l, r))
|
C#
using System;
class GFG
{
static int msb( int x)
{
int ret = 0;
while ((x >> (ret + 1)) != 0)
ret++;
return ret;
}
static int xorRange( int l, int r)
{
int max_bit = msb(r);
int mul = 2;
int ans = 0;
for ( int i = 1; i <= max_bit; i++)
{
if ((l / mul) * mul == (r / mul) * mul)
{
if (((l & (1 << i)) != 0) && (r - l + 1) % 2 == 1)
ans += mul;
mul *= 2;
continue ;
}
int odd_c = 0;
if (((l & (1 << i)) != 0) && l % 2 == 1)
odd_c = (odd_c ^ 1);
if (((r & (1 << i)) != 0) && r % 2 == 0)
odd_c = (odd_c ^ 1);
if (odd_c!=0)
ans += mul;
mul *= 2;
}
int zero_bit_cnt = zero_bit_cnt = (r - l + 1) / 2;
if (l % 2 == 1 && r % 2 == 1)
zero_bit_cnt++;
if (zero_bit_cnt % 2 == 1)
ans++;
return ans;
}
public static void Main(String []args)
{
int l = 1, r = 4;
Console.Write(xorRange(l, r));
}
}
|
PHP
<?php
function msb( $x )
{
$ret = 0;
while (( $x >> ( $ret + 1)) != 0)
$ret ++;
return $ret ;
}
function xorRange( $l , $r )
{
$max_bit = msb( $r );
$mul = 2;
$ans = 0;
for ( $i = 1; $i <= $max_bit ; $i ++)
{
if ((int)(( $l / $mul ) * $mul ) ==
(int)(( $r / $mul ) * $mul ))
{
if ((( $l & (1 << $i )) != 0) &&
( $r - $l + 1) % 2 == 1)
$ans += $mul ;
$mul *= 2;
continue ;
}
$odd_c = 0;
if ((( $l & (1 << $i )) != 0) && $l % 2 == 1)
$odd_c = ( $odd_c ^ 1);
if ((( $r & (1 << $i )) != 0) && $r % 2 == 0)
$odd_c = ( $odd_c ^ 1);
if ( $odd_c )
$ans += $mul ;
$mul *= 2;
}
$zero_bit_cnt = (int)(( $r - $l + 1) / 2);
if ( $l % 2 == 1 && $r % 2 == 1)
$zero_bit_cnt ++;
if ( $zero_bit_cnt % 2 == 1)
$ans ++;
return $ans ;
}
$l = 1;
$r = 4;
echo xorRange( $l , $r );
?>
|
Javascript
<script>
function msb(x)
{
let ret = 0;
while ((x >> (ret + 1)) != 0)
ret++;
return ret;
}
function xorRange(l, r)
{
let max_bit = msb(r);
let mul = 2;
let ans = 0;
for (let i = 1; i <= max_bit; i++) {
if ((parseInt(l / mul) * mul) ==
(parseInt(r / mul) * mul))
{
if (((l & (1 << i)) != 0) &&
(r - l + 1) % 2 == 1)
ans += mul;
mul *= 2;
continue ;
}
let odd_c = 0;
if (((l & (1 << i)) != 0) && l % 2 == 1)
odd_c = (odd_c ^ 1);
if (((r & (1 << i)) != 0) && r % 2 == 0)
odd_c = (odd_c ^ 1);
if (odd_c)
ans += mul;
mul *= 2;
}
let zero_bit_cnt = parseInt((r - l + 1) / 2);
if (l % 2 == 1 && r % 2 == 1)
zero_bit_cnt++;
if (zero_bit_cnt % 2 == 1)
ans++;
return ans;
}
let l = 1, r = 4;
document.write(xorRange(l, r));
</script>
|
Time Complexity: O(log2(R))
Auxiliary Space: O(1), since no extra space has been taken.
Efficient Approach: Let F(N) be a function that computes XOR of all the natural numbers less than or equal to N. Thus, for range (L-R), the answer will be F(R) ^ F(L-1).
Finding the value of this function for any given number is possible in O(1) as discussed in this article.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
long computeXOR( const int n)
{
switch (n & 3) {
case 0:
return n;
case 1:
return 1;
case 2:
return n + 1;
case 3:
return 0;
}
}
int main()
{
int l = 1, r = 4;
cout << (computeXOR(r) ^ computeXOR(l - 1));
return 0;
}
|
Java
class GFG
{
static long computeXOR( int n)
{
int x = n & 3 ;
switch (x)
{
case 0 :
return n;
case 1 :
return 1 ;
case 2 :
return n + 1 ;
case 3 :
return 0 ;
}
return 0 ;
}
public static void main(String args[])
{
int l = 1 , r = 4 ;
System.out.println(computeXOR(r) ^
computeXOR(l - 1 ));
}
}
|
Python3
def computeXOR(n) :
switch = {
0 : n,
1 : 1 ,
2 : n + 1 ,
3 : 0 ,
}
return switch.get( n & 3 , "")
l = 1
r = 4
print (computeXOR(r) ^ computeXOR(l - 1 ))
|
C#
using System;
class GFG
{
static long computeXOR( int n)
{
int x=n&3;
switch (x)
{
case 0:
return n;
case 1:
return 1;
case 2:
return n + 1;
case 3:
return 0;
}
return 0;
}
static void Main()
{
int l = 1, r = 4;
Console.WriteLine(computeXOR(r) ^ computeXOR(l - 1));
}
}
|
PHP
<?php
function computeXOR( $n )
{
$x = $n & 3;
switch ( $x )
{
case 0:
return $n ;
case 1:
return 1;
case 2:
return $n + 1;
case 3:
return 0;
}
return 0;
}
$l = 1; $r = 4;
echo (computeXOR( $r ) ^ computeXOR( $l - 1));
?>
|
Javascript
<script>
function computeXOR(n)
{
switch (n & 3) {
case 0:
return n;
case 1:
return 1;
case 2:
return n + 1;
case 3:
return 0;
}
}
let l = 1, r = 4;
document.write(computeXOR(r) ^ computeXOR(l - 1));
</script>
|
Time Complexity: O(1)
Auxiliary Space: O(1)
Last Updated :
09 Jun, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...