Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Queries to count array elements from a given range having a single set bit

  • Difficulty Level : Medium
  • Last Updated : 15 Nov, 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:

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.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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-exclusion principle).

Below is the implementation of the above approach:

C++




// 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)
{
    // Initialize 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;
}

Java




// JAVA program for the above approach
import java.util.*;
import java.io.*;
import java.math.*;
public class GFG
{
 
  // Function to check whether
  // only one bit is set or not
  static int check(int x)
  {
    if (((x) & (x - 1)) == 0)
      return 1;
 
    return 0;
  }
 
  // Function to perform Range-query
  static 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
  static void countInRange(int[] arr, int N,  ArrayList<Pair> queries,
                           int Q)
  {
 
    // Initialize array for Prefix sum
    int[] pre = new int[N];
    pre[0] = check(arr[0]);
    for(int i = 1; i < N; i++)
    {
      pre[i] = pre[i - 1] + check(arr[i]);
    }  
    int c = 0;
    int q = 0;   
    while (q < Q)
    {
      int l = queries.get(q).item1;
      int r = queries.get(q).item2;
      c++;
      q++;
      System.out.print(query(l, r, pre) + " ");
    }
  }
 
  // A Pair class for handling queries in JAVA
  // As, there is no in-built function of Tuple
  static class Pair
  {
    int item1, item2;
    Pair(int item1, int item2)
    {
      this.item1 = item1;
      this.item2 = item2;
    }
  }
 
  // Driver code
  public static void main(String args[])
  {
 
    // Given array
    int[] arr = { 12, 11, 16, 8, 2,
                 5, 1, 3, 256, 1 };
 
    // Size of the array
    int N = arr.length;
 
    // Given queries
    ArrayList<Pair> queries = new ArrayList<Pair>();
    queries.add(new Pair(4,9));
    queries.add(new Pair(0,9));
 
    // Size of queries array
    int Q = queries.size();    
    countInRange(arr, N, queries, Q);
  }
}
 
// This code is contributed by jyoti369

Python3




# Python 3 program for the above approach
 
# Function to check whether
# only one bit is set or not
def check(x):
    if (((x) & (x - 1)) == 0):
        return 1
    return 0
 
# Function to perform Range-query
def query(l, r, 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
def countInRange(arr,  N, queries, Q):
 
    # Initialize array for Prefix sum
    pre = [0] * N
    pre[0] = check(arr[0])
    for i in range(1, N):
        pre[i] = pre[i - 1] + check(arr[i])
    c = 0
    while (Q > 0):
        l = queries[0]
        r = queries[1]
        c += 1
        print(query(l, r, pre), end=" ")
        Q -= 1
 
 
# Driver Code
if __name__ == "__main__":
 
    # Given array
    arr = [12, 11, 16, 8, 2, 5, 1, 3, 256, 1]
 
    # Size of the array
    N = len(arr)
 
    # Given queries
    queries = [[0, 9], [4, 9]]
 
    # Size of queries array
    Q = len(queries)
 
    countInRange(arr, N, queries, Q)
 
    # this code is contributed by chitranayal.

C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
     
// Function to check whether
// only one bit is set or not
static int check(int x)
{
    if (((x) & (x - 1)) == 0)
        return 1;
         
    return 0;
}
   
// Function to perform Range-query
static 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
static void countInRange(int[] arr, int N,
                         List<Tuple<int, int>> queries,
                         int Q)
{
     
    // Initialize array for Prefix sum
    int[] pre = new int[N];
    pre[0] = check(arr[0]);
   
    for(int i = 1; i < N; i++)
    {
        pre[i] = pre[i - 1] + check(arr[i]);
    }
   
    int c = 0;
    int q = 0;
     
    while (q < Q)
    {
        int l = queries[q].Item1;
        int r = queries[q].Item2;
        c++;
        q++;
        Console.Write(query(l, r, pre) + " ");
    }
}
 
// Driver code
static void Main()
{
     
    // Given array
    int[] arr = { 12, 11, 16, 8, 2,
                  5, 1, 3, 256, 1 };
     
    // Size of the array
    int N = arr.Length;
     
    // Given queries
    List<Tuple<int,
               int>> queries = new List<Tuple<int,
                                              int>>();
    queries.Add(new Tuple<int, int>(0, 9));
    queries.Add(new Tuple<int, int>(4, 9));
     
    // Size of queries array
    int Q = queries.Count;
     
    countInRange(arr, N, queries, Q);
}
}
 
// This code is contributed by divyeshrabadiya07

Javascript




<script>
 
// JavaScript program for the above approach
 
 
// Function to check whether
// only one bit is set or not
function check(x)
{
    if (((x) & (x - 1)) == 0)
        return 1;
    return 0;
}
 
// Function to perform Range-query
function query(l, r, 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
function countInRange(arr, N, queries, Q)
{
    // Initialize array for Prefix sum
    var pre = Array(N).fill(0);
    pre[0] = check(arr[0]);
 
    for (var i = 1; i < N; i++) {
        pre[i] = pre[i - 1] + check(arr[i]);
    }
 
    var c = 0;
    while (Q--) {
        var l = queries[0];
        var r = queries[1];
        c++;
        document.write( query(l, r, pre) + ' ');
    }
}
 
// Driver Code
 
// Given array
var arr = [12, 11, 16, 8, 2, 5, 1, 3, 256, 1];
 
// Size of the array
var N = arr.length;
 
// Given queries
var queries
    = [[0, 9], [4, 9 ]];
     
// Size of queries array
var Q = queries.length;
 
countInRange(arr, N, queries, Q);
 
</script>
Output: 
6 4

 

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

 




My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!