The Wayback Machine - https://web.archive.org/web/20210126024814/https://www.geeksforgeeks.org/queries-to-count-array-elements-from-a-given-range-having-a-single-set-bit/
Related Articles

Related Articles

Queries to count array elements from a given range having a single set bit
  • Difficulty Level : Medium
  • Last Updated : 25 Jan, 2021

Given an array arr[] consisting of positive integers and an array Q[][] consisting of queries, the task for every ith query is to count array elements from the range [Q[i][0], Q[i][1]] with only one set bit.

Examples:

Input: arr[] = {12, 11, 16, 8, 2, 5, 1, 3, 256, 1}, queries[][] = {{0, 9}, {4, 9}}
Output: 6 4
Explanation:
In the range of indices [0, 9], the elements arr[2] (= 16), arr[3](= 8), arr[4]( = 2), arr[6](= 1), arr[8](= 256), arr[9](= 1) have only 1 set bit.
In the range [4, 9], the elements arr[4] (= 2), arr[6](= 1), arr[8](= 256), arr[9] (= 1) have only 1 set bit.

Input: arr[] = {2, 1, 101, 11, 4}, queries[][] = {{2, 4}, {1, 4}}
Output: 1 2

Naive Approach: The simplest approach for each query, is to iterate the range [l, r] and count the number of array elements having only one set bit by using Brian Kernighan’s Algorithm.
Time Complexity: O(Q * N*logN)
Auxiliary Space: O(1)

Efficient Approach: Follow the steps below to optimize the above approach:



  • Initialize a prefix sum array to store the number of elements with only one set bit.
  • The i-th index stores the count of array elements with only one set bit upto the ith index.
  • For each query (i, j), return pre[j] – pre[i – 1], i.e. (inclusion-exculsion principle).

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
  
#include <bits/stdc++.h>
using namespace std;
  
// Function to check whether
// only one bit is set or not
int check(int x)
{
    if (((x) & (x - 1)) == 0)
        return 1;
    return 0;
}
  
// Function to perform Range-query
int query(int l, int r, int pre[])
{
    if (l == 0)
        return pre[r];
    else
        return pre[r] - pre[l - 1];
}
  
// Function to count array elements with a
// single set bit for each range in a query
void countInRange(int arr[], int N,
                  vector<pair<int, int> > queries, int Q)
{
    // Intialize array for Prefix sum
    int pre[N] = { 0 };
    pre[0] = check(arr[0]);
  
    for (int i = 1; i < N; i++) {
        pre[i] = pre[i - 1] + check(arr[i]);
    }
  
    int c = 0;
    while (Q--) {
        int l = queries.first;
        int r = queries.second;
        c++;
        cout << query(l, r, pre) << ' ';
    }
}
  
// Driver Code
int main()
{
    // Given array
    int arr[] = { 12, 11, 16, 8, 2, 5, 1, 3, 256, 1 };
  
    // Size of the array
    int N = sizeof(arr) / sizeof(arr[0]);
  
    // Given queries
    vector<pair<int, int> > queries
        = { { 0, 9 }, { 4, 9 } };
  
    // Size of queries array
    int Q = queries.size();
  
    countInRange(arr, N, queries, Q);
  
    return 0;
}

chevron_right


Output:

6 4

Time Complexity: O(N*log(max(arr[i])))
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up
Recommended Articles
Page :