Find the number of subarrays have bitwise OR >= K using C++

C++Server Side ProgrammingProgramming

In this article, we will provide a brief explanation on solving the number of subarrays that have bitwise OR>=K in C++. So we have an array arr[] and an integer K, and we have to find the number of subarrays that have OR(bitwise or) greater than or equal to K. So here is the example of the given problem −

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 ≥ 3
Input: arr[] = {3, 4, 5} K = 6
Output: 2

Approaches to Find the Solution

Now we will use two different methods to solve the problem using C++ −

Brute Force

In this approach, we are simply going to go through all the subarrays that can be formed and check if OR is greater than or equal to K or not. If yes, then we are going to increment our answer.

Example

#include <bits/stdc++.h>
using namespace std;
int main(){
int arr[] = {1, 2, 3}; // given array.
int k = 3;
int size = sizeof(arr) / sizeof(int); // the size of our array.
int answer = 0; // the counter variable.
for(int i = 0; i < size; i++){
int bitwise = 0; // the variable that we compare to k.
for(int j = i; j < size; j++){ // all the subarrays starting from i.
bitwise = bitwise | arr[j];
if(bitwise >= k) // if bitwise >= k increment answer.
}
}
return 0;
}

Output

4

This approach is very simple, but it has its flaws as this approach is not very good for higher constraints as for higher constraints, it's going to take too much time as the time complexity of this approach is O(N*N) where N is the size of the given array so now we are going for an efficient approach.

Efficient Approach

In this approach, we are going to use some properties of the OR operator, which is that it never decreases even if we add more numbers, so if we get a subarray from i to j that has OR greater or equal to K, so every subarray that includes range {i,j} will have OR more than K, and we are taking advantage of this property and improve our code.

Example

#include <bits/stdc++.h>
#define N 1000
using namespace std;
int t[4*N];
void build(int* a, int v, int start, int end){ // segment tree building
if(start == end){
t[v] = a[start];
return;
}
int mid = (start + end)/2;
build(a, 2 * v, start, mid);
build(a, 2 * v + 1, mid + 1, end);
t[v] = t[2 * v] | t[2 * v + 1];
}
int query(int v, int tl, int tr, int l, int r){ // for processing our queries or subarrays.
if (l > r)
return 0;
if(tl == l && tr == r)
return t[v];
int tm = (tl + tr)/2;
int q1 = query(2*v, tl, tm, l, min(tm, r));
int q2 = query((2*v)+1, tm+1, tr, max(tm+1, l), r);
return q1 | q2;
}
int main(){
int arr[] = {1, 2, 3}; // given array.
int k = 3;
int size = sizeof(arr) / sizeof(arr[0]); // the size of our array.
int answer = 0; // the counter variable.
build(arr, 1, 0, size - 1); // building segment tree.
for(int i = 0; i < size; i++){
int start = i, end = size-1;
int ind = INT_MAX;
while(start <= end){ // binary search
int mid = (start + end) / 2;
if(query(1, 0, size-1, i, mid) >= k){ // checking subarray.
ind = min(mid, ind);
end = mid - 1;
}
else
start = mid + 1;
}
if(ind != INT_MAX) // if ind is changed then increment the answer.
}
return 0;
}

Output

4

In this approach, we are using binary search and segment tree, which are helping in reducing our time complexity from O(N*N) to O(Nlog(N)), which is very good. Now, this program can also work for bigger constraints, unlike the previous one.

Conclusion

In this article, we solve a problem to find the Number of subarrays having OR >= K in O(nlog(n)) time complexity using the Binary Search and Segment Tree. We also learned the C++ program for this problem and the complete approach ( Normal and efficient ) by which we solved this problem. We can write the same program in other languages such as C, java, python, and other languages. Hope you find this article helpful.

Published on 24-Nov-2021 12:26:43