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

 `= ``\$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 ` `?> `

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

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

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++ 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 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# 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).

An enthusiastic Java and web developer with a little affinity for tea, cricket, English, etymology, and reading

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.