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++
// 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; } |
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.

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.
