Count numbers in the range [L, R] having only three set bits - GeeksforGeeks

24 Jun, 2021
Given an array arr[] of N pairs, where each array element denotes a query of the form {L, R}, the task is to find the count of numbers in the range [L, R], having only 3-set bits for each query {L, R}.
Examples:
Input: arr[] = {{11, 19}, {14, 19}}Output: 4             2Explanation: 
Query(11, 19): Numbers in the range [11, 19] having three set bits are {11, 13, 14, 19}.Query(14, 19): Numbers in the range [14, 19] having three set bits are {14, 19}.
Query(11, 19): Numbers in the range [11, 19] having three set bits are {11, 13, 14, 19}.
Query(14, 19): Numbers in the range [14, 19] having three set bits are {14, 19}.
Input: arr[] = {{1, 10}, {6, 12}}Output: 1              2Explanation: 
Query(1, 10): Numbers in the range [1, 10] having three set bits are {7}.Query(6, 12): Numbers in the range [6, 12] having three set bits are {7, 12}.
Query(1, 10): Numbers in the range [1, 10] having three set bits are {7}.
Query(6, 12): Numbers in the range [6, 12] having three set bits are {7, 12}.
Approach: The idea to solve this problem is to do a pre-computation and store all the numbers with only 3 bits set in the range [1, 1018], and then use binary search to find the position of lowerbound of L and upperbound of R and return the answer as there difference. Follow the steps below to solve the given problem:
Initialize a vector, say V, to store all the numbers in the range [1, 1018] with only three bits set.
Iterate over every triplet formed of the relation [0, 63]×[0, 63]×[0, 63] using variables i, j, and k and perform the following steps:If i, j, and k are distinct, then compute the number with the ith, jth, and kth bit set, and if the number is less than 1018, push the number in the vector V.
If i, j, and k are distinct, then compute the number with the ith, jth, and kth bit set, and if the number is less than 1018, push the number in the vector V.
Sort the vector V in ascending order.
Traverse the array arr[], using the variable i, and perform the following steps:Store the boundaries of the query in the variables, say L and R, respectively.Find the position of the lowerbound of L and upperbound of R in the vector V.Print the difference between the positions of the upper bound of R and the lower bound of L, as the result.
Store the boundaries of the query in the variables, say L and R, respectively.
Find the position of the lowerbound of L and upperbound of R in the vector V.
Print the difference between the positions of the upper bound of R and the lower bound of L, as the result.
Below is the implementation of the above approach:
C++
// C++ program for the above approach#include <bits/stdc++.h>using namespace std;  // Function to precomputevoid precompute(vector<long long>& v){    // Iterate over the range [0, 64]    for (long long i = 0; i < 64; i++) {        // Iterate over the range [0, 64]        for (long long j = i + 1; j < 64; j++) {            // Iterate over the range [0, 64]            for (long long k = j + 1; k < 64; k++) {                  // Stores the number with set bits                // i, j, and k                long long int x                    = (1LL << i) | (1LL << j) | (1LL << k);                  // Check if the number is less                // than 1e18                if (x <= 1e18 && x > 0)                    v.push_back(x);            }        }    }      // Sort the computed vector    sort(v.begin(), v.end());}  // Function to count number in the range// [l, r] having three set bitslong long query(long long l, long long r,                vector<long long>& v){    // Find the lowerbound of l in v    auto X = lower_bound(v.begin(), v.end(), l);      // Find the upperbound of l in v    auto Y = upper_bound(v.begin(), v.end(), r);      // Return the difference    // in their positions    return (Y - X);}void PerformQuery(vector<pair<long long, long long> > arr,                  int N){      // Stores all the numbers in the range    // [1, 1e18] having three set bits    vector<long long> V;      // Function call to perform the    // precomputation    precompute(V);      // Iterate through each query    for (auto it : arr) {        long long L = it.first;        long long R = it.second;          // Print the answer        cout << query(L, R, V) << "\n";    }}  // Driver Codeint main(){      // Input    vector<pair<long long, long long> > arr        = { { 11, 19 }, { 14, 19 } };    int N = arr.size();      // Function call    PerformQuery(arr, N);      return 0;}
4
2
Time Complexity: O(N*log(633)+ 633)Auxiliary Space: O(633)
Bit Algorithms
setBitCount
Bit Magic
Mathematical
Mathematical
Bit Magic
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Set, Clear and Toggle a given bit of a number in C
Check whether K-th bit is set or not
Program to find parity
Hamming code Implementation in C/C++
Write an Efficient Method to Check if a Number is Multiple of 3
Program for Fibonacci numbers
Write a program to print all permutations of a given string
C++ Data Types
Set in C++ Standard Template Library (STL)
Coin Change | DP-7