Queries for bitwise AND in the index range [L, R] of the given array

26 Nov, 2021
Given an array arr[] of N and Q queries consisting of a range [L, R]. the task is to find the bit-wise AND of all the elements of in that index range.Examples:  
Input: arr[] = {1, 3, 1, 2, 3, 4}, q[] = {{0, 1}, {3, 5}} Output: 1 0 1 AND 3 = 1 2 AND 3 AND 4 = 0Input: arr[] = {1, 2, 3, 4, 5}, q[] = {{0, 4}, {1, 3}} Output: 0 0  
 
Naive approach: Iterate through the range and find bit-wise AND of all the numbers in that range. This will take O(n) time for each query.Efficient approach: If we look at the integers as binary number, we can easily see that condition for ith bit of our answer to be set is that ith bit of all the integers in the range [L, R] should be set. So, we will calculate prefix-count for each bit. We will use this to find the number of integers in the range with ith bit set. If it is equal to the size of the range then the ith bit of our answer will also be set.Below is the implementation of the above approach:  
C++
Java
Python3
C#
Javascript
// C++ implementation of the approach#include <bits/stdc++.h>#define MAX 100000#define bitscount 32using namespace std; // Array to store bit-wise// prefix countint prefix_count[bitscount][MAX]; // Function to find the prefix sumvoid findPrefixCount(int arr[], int n){     // Loop for each bit    for (int i = 0; i < bitscount; i++) {         // Loop to find prefix count        prefix_count[i][0] = ((arr[0] >> i) & 1);        for (int j = 1; j < n; j++) {            prefix_count[i][j] = ((arr[j] >> i) & 1);            prefix_count[i][j] += prefix_count[i][j - 1];        }    }} // Function to answer queryint rangeAnd(int l, int r){     // To store the answer    int ans = 0;     // Loop for each bit    for (int i = 0; i < bitscount; i++) {        // To store the number of variables        // with ith bit set        int x;        if (l == 0)            x = prefix_count[i][r];        else            x = prefix_count[i][r]                - prefix_count[i][l - 1];         // Condition for ith bit        // of answer to be set        if (x == r - l + 1)            ans = (ans | (1 << i));    }     return ans;} // Driver codeint main(){    int arr[] = { 7, 5, 3, 5, 2, 3 };    int n = sizeof(arr) / sizeof(int);     findPrefixCount(arr, n);     int queries[][2] = { { 1, 3 }, { 4, 5 } };    int q = sizeof(queries) / sizeof(queries[0]);     for (int i = 0; i < q; i++)        cout << rangeAnd(queries[i][0],                         queries[i][1])             << endl;     return 0;}
// Java implementation of the approachimport java.io.*; class GFG{     static int MAX = 100000;static int bitscount =32; // Array to store bit-wise// prefix countstatic int [][]prefix_count = new int [bitscount][MAX]; // Function to find the prefix sumstatic void findPrefixCount(int arr[], int n){     // Loop for each bit    for (int i = 0; i < bitscount; i++)    {         // Loop to find prefix count        prefix_count[i][0] = ((arr[0] >> i) & 1);        for (int j = 1; j < n; j++)        {            prefix_count[i][j] = ((arr[j] >> i) & 1);            prefix_count[i][j] += prefix_count[i][j - 1];        }    }} // Function to answer querystatic int rangeAnd(int l, int r){     // To store the answer    int ans = 0;     // Loop for each bit    for (int i = 0; i < bitscount; i++)    {        // To store the number of variables        // with ith bit set        int x;        if (l == 0)            x = prefix_count[i][r];        else            x = prefix_count[i][r]                - prefix_count[i][l - 1];         // Condition for ith bit        // of answer to be set        if (x == r - l + 1)            ans = (ans | (1 << i));    }     return ans;} // Driver codepublic static void main (String[] args){     int arr[] = { 7, 5, 3, 5, 2, 3 };    int n = arr.length;         findPrefixCount(arr, n);         int queries[][] = { { 1, 3 }, { 4, 5 } };    int q = queries.length;         for (int i = 0; i < q; i++)                System.out.println (rangeAnd(queries[i][0],queries[i][1]));          }} // This code is contributed by ajit.
# Python3 implementation of the approach import numpy as np MAX = 100000bitscount = 32 # Array to store bit-wise# prefix countprefix_count = np.zeros((bitscount,MAX)); # Function to find the prefix sumdef findPrefixCount(arr, n) :     # Loop for each bit    for i in range(0, bitscount) :                 # Loop to find prefix count        prefix_count[i][0] = ((arr[0] >> i) & 1);                 for j in range(1, n) :            prefix_count[i][j] = ((arr[j] >> i) & 1);            prefix_count[i][j] += prefix_count[i][j - 1]; # Function to answer querydef rangeOr(l, r) :     # To store the answer    ans = 0;     # Loop for each bit    for i in range(bitscount) :                 # To store the number of variables        # with ith bit set        x = 0;                 if (l == 0) :            x = prefix_count[i][r];        else :            x = prefix_count[i][r] - prefix_count[i][l - 1];                     # Condition for ith bit        # of answer to be set        if (x == r - l + 1) :            ans = (ans | (1 << i));                 return ans;  # Driver codeif __name__ == "__main__" :     arr = [ 7, 5, 3, 5, 2, 3 ];    n = len(arr);     findPrefixCount(arr, n);     queries = [ [ 1, 3 ], [ 4, 5 ] ];         q = len(queries);     for i in range(q) :        print(rangeOr(queries[i][0], queries[i][1]));  # This code is contributed by AnkitRai01
// C# implementation of the approachusing System; class GFG{     static int MAX = 100000;static int bitscount =32; // Array to store bit-wise// prefix countstatic int [,]prefix_count = new int [bitscount,MAX]; // Function to find the prefix sumstatic void findPrefixCount(int []arr, int n){     // Loop for each bit    for (int i = 0; i < bitscount; i++)    {         // Loop to find prefix count        prefix_count[i,0] = ((arr[0] >> i) & 1);        for (int j = 1; j < n; j++)        {            prefix_count[i,j] = ((arr[j] >> i) & 1);            prefix_count[i,j] += prefix_count[i,j - 1];        }    }} // Function to answer querystatic int rangeAnd(int l, int r){     // To store the answer    int ans = 0;     // Loop for each bit    for (int i = 0; i < bitscount; i++)    {        // To store the number of variables        // with ith bit set        int x;        if (l == 0)            x = prefix_count[i,r];        else            x = prefix_count[i,r]                - prefix_count[i,l - 1];         // Condition for ith bit        // of answer to be set        if (x == r - l + 1)            ans = (ans | (1 << i));    }     return ans;} // Driver codepublic static void Main (String[] args){     int []arr = { 7, 5, 3, 5, 2, 3 };    int n = arr.Length;         findPrefixCount(arr, n);         int [,]queries = { { 1, 3 }, { 4, 5 } };    int q = queries.GetLength(0);         for (int i = 0; i < q; i++)            Console.WriteLine(rangeAnd(queries[i,0],queries[i,1]));         }} // This code contributed by Rajput-Ji
<script>       // Javascript implementation of the approach         let MAX = 100000;    let bitscount =32;     // Array to store bit-wise    // prefix count    let prefix_count = new Array(bitscount);         for (let i = 0; i < bitscount; i++)    {        prefix_count[i] = new Array(MAX);        for (let j = 0; j < MAX; j++)        {            prefix_count[i][j] = 0;        }    }     // Function to find the prefix sum    function findPrefixCount(arr, n)    {        // Loop for each bit        for (let i = 0; i < bitscount; i++)        {             // Loop to find prefix count            prefix_count[i][0] = ((arr[0] >> i) & 1);            for (let j = 1; j < n; j++)            {                prefix_count[i][j] = ((arr[j] >> i) & 1);                prefix_count[i][j] += prefix_count[i][j - 1];            }        }    }     // Function to answer query    function rangeAnd(l, r)    {         // To store the answer        let ans = 0;         // Loop for each bit        for (let i = 0; i < bitscount; i++)        {            // To store the number of variables            // with ith bit set            let x;            if (l == 0)                x = prefix_count[i][r];            else                x = prefix_count[i][r]                    - prefix_count[i][l - 1];             // Condition for ith bit            // of answer to be set            if (x == r - l + 1)                ans = (ans | (1 << i));        }         return ans;    }     let arr = [ 7, 5, 3, 5, 2, 3 ];    let n = arr.length;           findPrefixCount(arr, n);           let queries = [ [ 1, 3 ], [ 4, 5 ] ];    let q = queries.length;           for (let i = 0; i < q; i++)          document.write(rangeAnd(queries[i][0],queries[i][1]) + "</br>");</script>
1
2
 
Time complexity for pre-computation is O(n) and each query can be answered in O(1)
Auxiliary Space: O(bitcount * MAX) 
ankthon
jit_t
Rajput-Ji
rameshtravel07
subhammahato348
array-range-queries
Bitwise-AND
Arrays
Bit Magic
Dynamic Programming
Arrays
Dynamic Programming
Bit Magic
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum and minimum of an array using minimum number of comparisons
Top 50 Array Coding Problems for Interviews
Multidimensional Arrays in Java
Stack Data Structure (Introduction and Program)
Linear Search
Left Shift and Right Shift Operators in C/C++
Travelling Salesman Problem | Set 1 (Naive and Dynamic Programming)
How to swap two numbers without using a temporary variable?
Program to find whether a given number is power of 2
Little and Big Endian Mystery