Find all M in range [2, N] such that bitwise OR till M is equal to the value till M-1
Given an integer N, the task is to find all possible integer M in the range [2, N] such that the bitwise OR of all positive values till M is the same as the bitwise OR of all positive values till M-1.
Examples:
Input: N = 4
Output: 1
Explanation: Bitwise OR till 3 = 1 | 2 | 3 = 3.
Bitwise OR till 2 = 1 | 2 = 3.
Input: N = 7
Output: 4
Approach: The approach to solve this problem is based on the following observation:
Consider p(x) to the bitwise OR till x. So p(x) = 1 | 2 | 3 | . . . | (x-1) | x
Given p(x) = 1 | 2 | 3 | . . . | x – 1 | x. Therefore, p(x + 1) will be different from p(x) if there is a new “1” bit in (x + 1) that isn’t present in the binary sequence of p(x).
Now, let us observe the pattern:
Decimal Number |
Binary Number |
1 |
1 |
2 |
10 |
3 |
11 |
4 |
100 |
5 |
101 |
6 |
110 |
7 |
111 |
8 |
1000 |
9 |
1001 |
We can see that a new “1” bit that hasn’t previously appeared in the range [1, x] appears at every power of 2.
As such, p(x) = 1 | 2 | 3 | . . . | x – 1 | x
= 2a+1 – 1, where a = log2x.
This implies that, for a given a, there will be ( 2a + 1 – 2a – 1 ) values of x where p(x) = p(x – 1).
Follow the step below to solve this problem:
- Calculate a = log2N.
- Iterate through the powers (say using variable exp) of 2 from 1 to a and increment ans (initially 0) by ( 2 exp + 1 – 2exp – 1 ).
- Finally, count for the pairs between N and 2a by adding (n – 2a) to ans.
C++
#include <bits/stdc++.h>
using namespace std;
int checkXORrange( int n)
{
int ans = 0;
int a = log2(n);
for ( int exp = 1; exp <= a; exp ++)
ans += pow (2, exp ) - pow (2, exp - 1) - 1;
ans += n - pow (2, a);
return ans;
}
int main()
{
int N = 7;
cout << checkXORrange(N) << endl;
return 0;
}
|
C
#include <math.h>
#include <stdio.h>
int checkXORrange( int n)
{
int ans = 0;
int a = log2(n);
for ( int exp = 1; exp <= a; exp ++)
ans += pow (2, exp ) - pow (2, exp - 1) - 1;
ans += n - pow (2, a);
return ans;
}
int main()
{
int N = 7;
printf ( "%d\n" , checkXORrange(N));
return 0;
}
|
Java
import java.io.*;
class GFG {
public static int log2( int N)
{
int result = ( int )(Math.log(N) / Math.log( 2 ));
return result;
}
public static int checkXORrange( int n)
{
int ans = 0 ;
int a = log2(n);
for ( int exp = 1 ; exp <= a; exp++)
ans += Math.pow( 2 , exp) - Math.pow( 2 , exp - 1 )
- 1 ;
ans += n - Math.pow( 2 , a);
return ans;
}
public static void main(String[] args)
{
int N = 7 ;
System.out.print(checkXORrange(N));
}
}
|
C#
using System;
public class GFG {
public static int checkXORrange( int n)
{
int ans = 0;
int a = ( int )Math.Log(n, 2);
for ( int exp = 1; exp <= a; exp++)
ans += ( int )(Math.Pow(2, exp)
- Math.Pow(2, exp - 1) - 1);
ans += ( int )(n - (Math.Pow(2, a)));
return ans;
}
public static void Main( string [] args)
{
int N = 7;
Console.Write(checkXORrange(N));
}
}
|
Python3
import math
def checkXORrange(n):
ans = 0
a = int (math.log2(n))
for exp in range ( 1 , a + 1 ):
ans + = 2 * * exp - 2 * * (exp - 1 ) - 1
ans + = n - 2 * * a
return ans
if __name__ = = "__main__" :
N = 7
print (checkXORrange(N))
|
Javascript
<script>
const checkXORrange = (n) => {
let ans = 0;
let a = parseInt(Math.log2(n));
for (let exp = 1; exp <= a; exp++)
ans += Math.pow(2, exp) - Math.pow(2, exp - 1) - 1;
ans += n - Math.pow(2, a);
return ans;
}
let N = 7;
document.write(checkXORrange(N));
</script>
|
Time Complexity: O(log2N)
Auxiliary Space: O(1)
Last Updated :
19 Apr, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...