Open In App

Number of subarrays have bitwise OR >= K

Last Updated : 13 Sep, 2022
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array arr[] and an integer K, the task is to count the number of sub-arrays having bitwise OR ? K.

Examples:

Input: arr[] = { 1, 2, 3 } K = 3 
Output: 4
Bitwise OR of sub-arrays: 
{ 1 } = 1 
{ 1, 2 } = 3 
{ 1, 2, 3 } = 3 
{ 2 } = 2 
{ 2, 3 } = 3 
{ 3 } = 3 
4 sub-arrays have bitwise OR ? K

Input: arr[] = { 3, 4, 5 } K = 6 
Output:

Naive approach: Run three nested loops. The outermost loop determines the starting of the sub-array. The middle loop determines the ending of the sub-array. The innermost loop traverses the sub-array whose bounds are determined by the outermost and middle loops. For every sub-array, calculate OR and update count = count + 1 if OR is greater than K

Below is the implementation of the above approach:  

C++
// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;

// Function to return the count of required sub-arrays
int countSubArrays(const int* arr, int n, int K)
{
    int count = 0;
    for (int i = 0; i < n; i++) {
        for (int j = i; j < n; j++) {

            int bitwise_or = 0;

            // Traverse sub-array [i..j]
            for (int k = i; k <= j; k++) {
                bitwise_or = bitwise_or | arr[k];
            }
            if (bitwise_or >= K)
                count++;
        }
    }
    return count;
}

// Driver code
int main()
{
    int arr[] = { 3, 4, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 6;
    cout << countSubArrays(arr, n, k);
    return 0;
}
Java
// Java implementation of the approach
import java.util.*;

class solution
{

// Function to return the count of required sub-arrays
static int countSubArrays(int arr[], int n, int K)
{
    int count = 0;
    for (int i = 0; i < n; i++) {
        for (int j = i; j < n; j++) {

            int bitwise_or = 0;

            // Traverse sub-array [i..j]
            for (int k = i; k <= j; k++) {
                bitwise_or = bitwise_or | arr[k];
            }
            if (bitwise_or >= K)
                count++;
        }
    }
    return count;
}

// Driver code
public static void main(String args[])
{
    int arr[] = { 3, 4, 5 };
    int n = arr.length;
    int k = 6;
    System.out.println(countSubArrays(arr, n, k));
  
}
}
// This code is contributed by
// Surendra_Gangwar
Python3
# Python3 implementation of the approach 

# Function to return the count of
# required sub-arrays 
def countSubArrays(arr, n, K) :
    
    count = 0; 
    for i in range(n) :
        for j in range(i, n) :

            bitwise_or = 0

            # Traverse sub-array [i..j] 
            for k in range(i, j + 1) :
                bitwise_or = bitwise_or | arr[k] 
            
            if (bitwise_or >= K) :
                count += 1
                
    return count 

# Driver code 
if __name__ == "__main__" :

    arr = [ 3, 4, 5 ]
    n = len(arr)
    k = 6
    
    print(countSubArrays(arr, n, k))

# This code is contributed by Ryuga
C#
// C# implementation of the approach
using System; 

class GFG
{

// Function to return the count of 
// required sub-arrays
static int countSubArrays(int []arr, 
                          int n, int K)
{
    int count = 0;
    for (int i = 0; i < n; i++)
    {
        for (int j = i; j < n; j++) 
        {
            int bitwise_or = 0;

            // Traverse sub-array [i..j]
            for (int k = i; k <= j; k++) 
            {
                bitwise_or = bitwise_or | arr[k];
            }
            if (bitwise_or >= K)
                count++;
        }
    }
    return count;
}

// Driver code
public static void Main()
{
    int []arr = { 3, 4, 5 };
    int n = arr.Length;
    int k = 6;
    Console.WriteLine(countSubArrays(arr, n, k));
}
}

// This code is contributed by
// Mohit kumar
PHP
<?php
// PHP implementation of the approach 

// Function to return the count of
// required sub-arrays 
function countSubArrays($arr, $n, $K) 
{ 
    $count = 0; 
    for ($i = 0; $i < $n; $i++)
    {
        for ($j = 0; $j < $n; $j++)
        {
            $bitwise_or = 0;

            // Traverse sub-array [i..j] 
            for ($k = $i; $k < $j + 1; $k++)
                $bitwise_or = $bitwise_or | $arr[$k]; 
            
            if ($bitwise_or >= $K)
                $count += 1;
        }
    }
    return $count; 
}

// Driver code 
$arr = array( 3, 4, 5 );
$n = count($arr);
$k = 6;

print(countSubArrays($arr, $n, $k));

// This code is contributed by mits
?>
JavaScript
<script>
    // Javascript implementation of the approach
    
    // Function to return the count of required sub-arrays
    function countSubArrays(arr, n, K)
    {
        let count = 0;
        for (let i = 0; i < n; i++) {
            for (let j = i; j < n; j++) {

                let bitwise_or = 0;

                // Traverse sub-array [i..j]
                for (let k = i; k <= j; k++) {
                    bitwise_or = bitwise_or | arr[k];
                }
                if (bitwise_or >= K)
                    count++;
            }
        }
        return count;
    }
    
    // Driver code
    let arr = [ 3, 4, 5 ];
    let n = arr.length;
    let k = 6;
    document.write(countSubArrays(arr, n, k));
    
    // This code is contributed by suresh07.
</script>

Output
2

The time complexity of the above solution is O(n3) and Auxiliary Space is O(1).   

An efficient solution uses segment trees to calculate bitwise OR of a sub-array in O(log n) time. Hence, now we directly query the segment tree instead of traversing the sub-array. 

Below is the implementation of the above approach: 

C++
// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;

#define N 100002
int tree[4 * N];

// Function to build the segment tree
void build(int* arr, int node, int start, int end)
{
    if (start == end) {
        tree[node] = arr[start];
        return;
    }
    int mid = (start + end) >> 1;
    build(arr, 2 * node, start, mid);
    build(arr, 2 * node + 1, mid + 1, end);
    tree[node] = tree[2 * node] | tree[2 * node + 1];
}

// Function to return the bitwise OR of segment [L..R]
int query(int node, int start, int end, int l, int r)
{
    if (start > end || start > r || end < l) {
        return 0;
    }

    if (start >= l && end <= r) {
        return tree[node];
    }

    int mid = (start + end) >> 1;
    int q1 = query(2 * node, start, mid, l, r);
    int q2 = query(2 * node + 1, mid + 1, end, l, r);
    return q1 | q2;
}

// Function to return the count of required sub-arrays
int countSubArrays(int arr[], int n, int K)
{

    // Build segment tree
    build(arr, 1, 0, n - 1);

    int count = 0;
    for (int i = 0; i < n; i++) {
        for (int j = i; j < n; j++) {

            // Query segment tree for bitwise OR
            // of sub-array [i..j]
            int bitwise_or = query(1, 0, n - 1, i, j);
            if (bitwise_or >= K)
                count++;
        }
    }
    return count;
}

// Driver code
int main()
{
    int arr[] = { 3, 4, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);

    int k = 6;
    cout << countSubArrays(arr, n, k);
    return 0;
}
Java
// Java implementation of the approach 
public class Main
{
  static int N = 100002;
  static int tree[] = new int[4 * N];

  // Function to build the segment tree 
  static void build(int arr[], int node, 
                    int start, int end) 
  { 
    if (start == end) { 
      tree[node] = arr[start]; 
      return; 
    } 
    int mid = (start + end) >> 1; 
    build(arr, 2 * node, start, mid); 
    build(arr, 2 * node + 1, mid + 1, end); 
    tree[node] = tree[2 * node] | tree[2 * node + 1]; 
  } 

  // Function to return the bitwise OR of segment [L..R] 
  static int query(int node, int start, 
                   int end, int l, int r) 
  { 
    if (start > end || start > r || end < l)
    { 
      return 0; 
    } 

    if (start >= l && end <= r)
    { 
      return tree[node]; 
    } 

    int mid = (start + end) >> 1; 
    int q1 = query(2 * node, start, mid, l, r); 
    int q2 = query(2 * node + 1, mid + 1, end, l, r); 
    return q1 | q2; 
  } 

  // Function to return the count of required sub-arrays 
  static int countSubArrays(int arr[], int n, int K) 
  { 

    // Build segment tree 
    build(arr, 1, 0, n - 1); 

    int count = 0; 
    for (int i = 0; i < n; i++)
    { 
      for (int j = i; j < n; j++) 
      { 

        // Query segment tree for bitwise OR 
        // of sub-array [i..j] 
        int bitwise_or = query(1, 0, n - 1, i, j); 
        if (bitwise_or >= K) 
          count++; 
      } 
    } 
    return count; 
  } 

  // Driver code
  public static void main(String[] args) 
  {
    int arr[] = { 3, 4, 5 }; 
    int n = arr.length; 

    int k = 6;
    System.out.print(countSubArrays(arr, n, k));
  }
}

// This code is contributed by divyesh072019
Python3
# Python implementation of the approach

N = 100002
tree = [0]*(4 * N)

# Function to build the segment tree
def build(arr, node, start, end):
    if start == end:
        tree[node] = arr[start]
        return
    mid = (start + end) >> 1
    build(arr, 2 * node, start, mid)
    build(arr, 2 * node + 1, mid + 1, end)
    tree[node] = tree[2 * node] | tree[2 * node + 1]

# Function to return the bitwise OR of segment[L..R]
def query(node, start, end, l, r):
    if start > end or start > r or end < l:
        return 0

    if start >= l and end <= r:
        return tree[node]

    mid = (start + end) >> 1
    q1 = query(2 * node, start, mid, l, r)
    q2 = query(2 * node + 1, mid + 1, end, l, r)
    return q1 or q2

# Function to return the count of required sub-arrays
def countSubArrays(arr, n, K):
    
    # Build segment tree
    build(arr, 1, 0, n - 1)

    count = 0
    for i in range(n):
        for j in range(n):

            # Query segment tree for bitwise OR
            # of sub-array[i..j]
            bitwise_or = query(1, 0, n - 1, i, j)
            if bitwise_or >= K:
                count += 1

    return count

# Driver code
arr = [3, 4, 5]
n = len(arr)

k = 6
print(countSubArrays(arr, n, k))

# This code is contributed by ankush_953
C#
// C# implementation of the approach 
using System;
class GFG {
    
  static int N = 100002;
  static int[] tree = new int[4 * N];
 
  // Function to build the segment tree 
  static void build(int[] arr, int node, 
                    int start, int end) 
  { 
    if (start == end) { 
      tree[node] = arr[start]; 
      return; 
    } 
    int mid = (start + end) >> 1; 
    build(arr, 2 * node, start, mid); 
    build(arr, 2 * node + 1, mid + 1, end); 
    tree[node] = tree[2 * node] | tree[2 * node + 1]; 
  } 
 
  // Function to return the bitwise OR of segment [L..R] 
  static int query(int node, int start, 
                   int end, int l, int r) 
  { 
    if (start > end || start > r || end < l)
    { 
      return 0; 
    } 
 
    if (start >= l && end <= r)
    { 
      return tree[node]; 
    } 
 
    int mid = (start + end) >> 1; 
    int q1 = query(2 * node, start, mid, l, r); 
    int q2 = query(2 * node + 1, mid + 1, end, l, r); 
    return q1 | q2; 
  } 
 
  // Function to return the count of required sub-arrays 
  static int countSubArrays(int[] arr, int n, int K) 
  { 
 
    // Build segment tree 
    build(arr, 1, 0, n - 1);  
    int count = 0; 
    for (int i = 0; i < n; i++)
    { 
      for (int j = i; j < n; j++) 
      { 
 
        // Query segment tree for bitwise OR 
        // of sub-array [i..j] 
        int bitwise_or = query(1, 0, n - 1, i, j); 
        if (bitwise_or >= K) 
          count++; 
      } 
    } 
    return count; 
  } 
  
  // Driver code
  static void Main() {
    int[] arr = { 3, 4, 5 }; 
    int n = arr.Length; 
 
    int k = 6;
    Console.WriteLine(countSubArrays(arr, n, k));
  }
}

// This code is contributed by divyeshrabadiya07.
JavaScript
<script>

// Javascript implementation of the approach
let N = 100002;
let tree = new Array(4 * N);

// Function to build the segment tree    
function build(arr, node, start, end)
{
    if (start == end)
    {
        tree[node] = arr[start];
        return;
    }
    let mid = (start + end) >> 1;
    build(arr, 2 * node, start, mid);
    build(arr, 2 * node + 1, mid + 1, end);
    tree[node] = tree[2 * node] | tree[2 * node + 1];
}

// Function to return the bitwise OR of segment [L..R]
function query(node, start, end, l, r)
{
    if (start > end || start > r || end < l)
    {
        return 0;
    }
 
    if (start >= l && end <= r)
    {
        return tree[node];
    }
 
    let mid = (start + end) >> 1;
    let q1 = query(2 * node, start, mid, l, r);
    let q2 = query(2 * node + 1, mid + 1, end, l, r);
    return q1 | q2;
}

// Function to return the count of 
// required sub-arrays
function countSubArrays(arr, n, K)
{
    
    // Build segment tree
    build(arr, 1, 0, n - 1);
 
    let count = 0;
    for(let i = 0; i < n; i++)
    {
        for(let j = i; j < n; j++)
        {
            
            // Query segment tree for bitwise OR
            // of sub-array [i..j]
            let bitwise_or = query(1, 0, n - 1, i, j);
            if (bitwise_or >= K)
                count++;
        }
    }
    return count;
}

// Driver code
let arr = [ 3, 4, 5 ];
let n = arr.length;
let k = 6;

document.write(countSubArrays(arr, n, k));

// This code is contributed by rag2127

</script>

Output
2

Complexity Analysis:

  • Time complexity: O(n2 log n).
  • Auxiliary Space: O(n).

A further efficient solution uses binary search. Bitwise OR is a function that never decreases with the number of inputs. For example:

OR(a, b) ? OR(a, b, c) 
OR(a1, a2, a3, ...) ? OR(a1, a2, a3, ..., b) 

By this property, OR(ai, ..., aj) <= OR(ai, ..., aj, aj+1). Hence, if OR(ai, ..., aj) is greater than K then OR(ai, ..., aj, aj+1) will also be greater than K. Hence, once we find a subarray [i..j] whose OR is greater than K, we don't need to check subarrays [i..j+1], [i..j+2], .. and so on, because their OR will also be greater than K. We can add the count of remaining subarrays to the current sum. The first subarray from a particular starting point whose OR is greater than K is found using binary search.

Below is the implementation of the above idea:  

C++
// C++ program to implement the above approach
#include <bits/stdc++.h>

#define N 100002
using namespace std;

int tree[4 * N];

// Function which builds the segment tree
void build(int* arr, int node, int start, int end)
{
    if (start == end) {
        tree[node] = arr[start];
        return;
    }
    int mid = (start + end) >> 1;
    build(arr, 2 * node, start, mid);
    build(arr, 2 * node + 1, mid + 1, end);
    tree[node] = tree[2 * node] | tree[2 * node + 1];
}

// Function that returns bitwise OR of segment [L..R]
int query(int node, int start, int end, int l, int r)
{
    if (start > end || start > r || end < l) {
        return 0;
    }

    if (start >= l && end <= r) {
        return tree[node];
    }

    int mid = (start + end) >> 1;
    int q1 = query(2 * node, start, mid, l, r);
    int q2 = query(2 * node + 1, mid + 1, end, l, r);
    return q1 | q2;
}

// Function to count requisite number of subarrays
int countSubArrays(const int* arr, int n, int K)
{
    int count = 0;
    for (int i = 0; i < n; i++) {

        // Check for subarrays starting with index i
        int low = i, high = n - 1, index = INT_MAX;
        while (low <= high) {

            int mid = (low + high) >> 1;

            // If OR of subarray [i..mid] >= K,
            // then all subsequent subarrays will have OR >= K
            // therefore reduce high to mid - 1
            // to find the minimal length subarray 
            // [i..mid] having OR >= K
            if (query(1, 0, n - 1, i, mid) >= K) {
                index = min(index, mid);
                high = mid - 1;
            }
            else {
                low = mid + 1;
            }
        }

        // Increase count with number of subarrays
        //  having OR >= K and starting with index i
        if (index != INT_MAX) {
            count += n - index;
        }
    }
    return count;
}

// Driver code
int main()
{
    int arr[] = { 3, 4, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
    // Build segment tree.
    build(arr, 1, 0, n - 1);
    int k = 6;
    cout << countSubArrays(arr, n, k);
    return 0;
}
Java
// Java implementation of the above approach
class GFG 
{

    static int N = 100002;

    static int tree[] = new int[4 * N];

    // Function which builds the segment tree 
    static void build(int[] arr, int node,
                    int start, int end)
    {
        if (start == end)
        {
            tree[node] = arr[start];
            return;
        }
        int mid = (start + end) >> 1;
        build(arr, 2 * node, start, mid);
        build(arr, 2 * node + 1, mid + 1, end);
        tree[node] = tree[2 * node] | tree[2 * node + 1];
    }

    // Function that returns bitwise
    // OR of segment [L..R] 
    static int query(int node, int start,
                    int end, int l, int r) 
    {
        if (start > end || start > r || end < l)
        {
            return 0;
        }

        if (start >= l && end <= r) 
        {
            return tree[node];
        }

        int mid = (start + end) >> 1;
        int q1 = query(2 * node, start, mid, l, r);
        int q2 = query(2 * node + 1, mid + 1, end, l, r);
        return q1 | q2;
    }

    // Function to count requisite number of subarrays 
    static int countSubArrays(int[] arr, 
                            int n, int K)
    {
        int count = 0;
        for (int i = 0; i < n; i++) 
        {

            // Check for subarrays starting with index i 
            int low = i, high = n - 1, index = Integer.MAX_VALUE;
            while (low <= high)
            {

                int mid = (low + high) >> 1;

                // If OR of subarray [i..mid] >= K, 
                // then all subsequent subarrays will
                // have OR >= K therefore reduce
                // high to mid - 1 to find the
                // minimal length subarray 
                // [i..mid] having OR >= K 
                if (query(1, 0, n - 1, i, mid) >= K)
                {
                    index = Math.min(index, mid);
                    high = mid - 1;
                } 
                else 
                {
                    low = mid + 1;
                }
            }

            // Increase count with number of subarrays 
            // having OR >= K and starting with index i 
            if (index != Integer.MAX_VALUE) 
            {
                count += n - index;
            }
        }
        return count;
    }

    // Driver code 
    public static void main(String[] args) 
    {
        int arr[] = {3, 4, 5};
        int n = arr.length;
        
        // Build segment tree. 
        build(arr, 1, 0, n - 1);
        int k = 6;
        System.out.println(countSubArrays(arr, n, k));
    }
}

// This code is contributed by Rajput-Ji
Python3
# Python3 program to implement the above approach
N = 100002
tree = [0 for i in range(4 * N)];

# Function which builds the segment tree
def build(arr, node, start, end):
    if (start == end):
        tree[node] = arr[start];
        return;   
    mid = (start + end) >> 1;
    build(arr, 2 * node, start, mid);
    build(arr, 2 * node + 1, mid + 1, end);
    tree[node] = tree[2 * node] | tree[2 * node + 1];

# Function that returns bitwise OR of segment [L..R]
def query(node, start, end, l, r):
    if (start > end or start > r or end < l):
        return 0;
    if (start >= l and end <= r):
        return tree[node];    
    mid = (start + end) >> 1;
    q1 = query(2 * node, start, mid, l, r);
    q2 = query(2 * node + 1, mid + 1, end, l, r);
    return q1 | q2;

# Function to count requisite number of subarrays
def countSubArrays(arr, n, K):
    count = 0;
    for i in range(n):

        # Check for subarrays starting with index i
        low = i
        high = n - 1
        index = 1000000000
        while (low <= high):
            mid = (low + high) >> 1;

            # If OR of subarray [i..mid] >= K,
            # then all subsequent subarrays will have OR >= K
            # therefore reduce high to mid - 1
            # to find the minimal length subarray 
            # [i..mid] having OR >= K
            if (query(1, 0, n - 1, i, mid) >= K):
                index = min(index, mid);
                high = mid - 1;           
            else :
                low = mid + 1;

        # Increase count with number of subarrays
        #  having OR >= K and starting with index i
        if (index != 1000000000):
            count += n - index;       
    return count;

# Driver code
if __name__=='__main__':
    arr = [ 3, 4, 5 ]
    n = len(arr)
    
    # Build segment tree.
    build(arr, 1, 0, n - 1);
    k = 6;
    print(countSubArrays(arr, n, k))
    
# This code is contributed by rutvik_56.
C#
// C# implementation of the above approach 
using System;

class GFG 
{ 

    static int N = 100002; 

    static int []tree = new int[4 * N]; 

    // Function which builds the segment tree 
    static void build(int[] arr, int node, 
                    int start, int end) 
    { 
        if (start == end) 
        { 
            tree[node] = arr[start]; 
            return; 
        } 
        int mid = (start + end) >> 1; 
        build(arr, 2 * node, start, mid); 
        build(arr, 2 * node + 1, mid + 1, end); 
        tree[node] = tree[2 * node] | tree[2 * node + 1]; 
    } 

    // Function that returns bitwise 
    // OR of segment [L..R] 
    static int query(int node, int start, 
                    int end, int l, int r) 
    { 
        if (start > end || start > r || end < l) 
        { 
            return 0; 
        } 

        if (start >= l && end <= r) 
        { 
            return tree[node]; 
        } 

        int mid = (start + end) >> 1; 
        int q1 = query(2 * node, start, mid, l, r); 
        int q2 = query(2 * node + 1, mid + 1, end, l, r); 
        return q1 | q2; 
    } 

    // Function to count requisite number of subarrays 
    static int countSubArrays(int[] arr, 
                            int n, int K) 
    { 
        int count = 0; 
        for (int i = 0; i < n; i++) 
        { 

            // Check for subarrays starting with index i 
            int low = i, high = n - 1, index = int.MaxValue; 
            while (low <= high) 
            { 

                int mid = (low + high) >> 1; 

                // If OR of subarray [i..mid] >= K, 
                // then all subsequent subarrays will 
                // have OR >= K therefore reduce 
                // high to mid - 1 to find the 
                // minimal length subarray 
                // [i..mid] having OR >= K 
                if (query(1, 0, n - 1, i, mid) >= K) 
                { 
                    index = Math.Min(index, mid); 
                    high = mid - 1; 
                } 
                else
                { 
                    low = mid + 1; 
                } 
            } 

            // Increase count with number of subarrays 
            // having OR >= K and starting with index i 
            if (index != int.MaxValue) 
            { 
                count += n - index; 
            } 
        } 
        return count; 
    } 

    // Driver code 
    public static void Main(String[] args) 
    { 
        int []arr = {3, 4, 5}; 
        int n = arr.Length; 
        
        // Build segment tree. 
        build(arr, 1, 0, n - 1); 
        int k = 6; 
        Console.WriteLine(countSubArrays(arr, n, k)); 
    } 
} 

// This code is contributed by PrinciRaj1992
JavaScript
<script>

// JavaScript implementation of the above approach

    let N = 100002;
    
    let tree=new Array(4*N);
    
    // Function which builds the segment tree
    function build(arr,node,start,end)
    {
         if (start == end)
        {
            tree[node] = arr[start];
            return;
        }
        let mid = (start + end) >> 1;
        build(arr, 2 * node, start, mid);
        build(arr, 2 * node + 1, mid + 1, end);
        tree[node] = tree[2 * node] | tree[2 * node + 1];
    }
    
    // Function that returns bitwise
    // OR of segment [L..R]
    function query(node,start,end,l,r)
    {
        if (start > end || start > r || end < l)
        {
            return 0;
        }
 
        if (start >= l && end <= r)
        {
            return tree[node];
        }
 
        let mid = (start + end) >> 1;
        let q1 = query(2 * node, start, mid, l, r);
        let q2 = query(2 * node + 1, mid + 1, end, l, r);
        return q1 | q2;
    }
    
    // Function to count requisite number of subarrays
    function countSubArrays(arr,n,K)
    {
        let count = 0;
        for (let i = 0; i < n; i++)
        {
 
            // Check for subarrays starting with index i
            let low = i, high = n - 1, index = Number.MAX_VALUE;
            while (low <= high)
            {
 
                let mid = (low + high) >> 1;
 
                // If OR of subarray [i..mid] >= K,
                // then all subsequent subarrays will
                // have OR >= K therefore reduce
                // high to mid - 1 to find the
                // minimal length subarray
                // [i..mid] having OR >= K
                if (query(1, 0, n - 1, i, mid) >= K)
                {
                    index = Math.min(index, mid);
                    high = mid - 1;
                }
                else
                {
                    low = mid + 1;
                }
            }
 
            // Increase count with number of subarrays
            // having OR >= K and starting with index i
            if (index != Number.MAX_VALUE)
            {
                count += n - index;
            }
        }
        return count;
    }
    
    // Driver code
    let arr=[3, 4, 5];
    let n = arr.length;
    // Build segment tree.
    build(arr, 1, 0, n - 1);
    let k = 6;
    document.write(countSubArrays(arr, n, k));


// This code is contributed by patel2127

</script>

Output
2

Complexity Analysis:

  • Time complexity: O(n log2 n).
  • Auxiliary Space: O(n).  

Next Article

Similar Reads