# Number of subarrays have bitwise OR >= K

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: 2

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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 ` `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 `

Output:

```2
```

The time complexity of the above solution is O(n3).

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++ implementation of the approach ` `#include ` `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; ` `} `

Output:

```2
```

The time complexity of the above solution is O(n2 log 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 ` ` `  `#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 `

## 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 `

Output:

```2
```

The time complexity of the above solution is O(n log2 n).

My Personal Notes arrow_drop_up

2

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.