Minimum removals in range to make bitwise AND non-zero for given range queries
Last Updated :
25 Apr, 2023
Given an array queries[][] of Q range queries, the task is to find the minimum removals from the range[l, r] such that the bitwise AND of the range is a non-zero value.
Examples:
Input: queries[][] = { {1, 5}, {3, 4}, {5, 10}, {10, 15}}
Output: 2 1 3 0
Explanation:
Query-1: l = 1, r = 5 {1, 2, 3, 4, 5} (2, 4 ) should be removed to make the AND of the array non-zero so minimum removals is 2.
Query-2: l = 3, r = 4 {3, 4} Either 3 or 4 should be removed to make the AND of the array non-zero so minimum removals is 1.
Query-3: l = 5, r = 10 {5, 6, 7, 8, 9, 10} (5, 6, 7) or (8, 9, 10) should be removed to make the AND of range non-zero. Minimum removals 3.
Query-4: l = 10, r = 15 {10, 11, 12, 13, 14, 15} the AND of the array is non-zero initially so 0 removals.
Input: queries[][] = { {100, 115}, {30, 40}, {101, 190} };
Output: 0 2 27
Naive Approach: This can be solved by iterating through every range and checking the max count of elements in the range having the common set bit and removing that from the total count of element i.e (r – l + 1).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void solve_queries(vector<vector< int > > q)
{
for ( int i = 0; i < q.size(); i++) {
int l = q[i][0];
int r = q[i][1];
int max_set = 0;
for ( int i = 0; i < 31; i++) {
int cnt = 0;
for ( int j = l; j <= r; j++) {
if ((1 << i) & j) {
cnt++;
}
}
max_set = max(max_set, cnt);
}
cout << (r - l + 1) - max_set << " " ;
}
}
int main()
{
vector<vector< int > > queries
= { { 1, 5 }, { 3, 4 }, { 5, 10 }, { 10, 15 } };
solve_queries(queries);
return 0;
}
|
Java
import java.util.*;
public class GFG
{
static void solve_queries( int [][]q)
{
for ( int i = 0 ; i < q.length; i++) {
int l = q[i][ 0 ];
int r = q[i][ 1 ];
int max_set = 0 ;
for ( int k = 0 ; k < 31 ; k++) {
int cnt = 0 ;
for ( int j = l; j <= r; j++) {
if ((( 1 << k) & j) != 0 ) {
cnt++;
}
}
max_set = Math. max(max_set, cnt);
}
System.out.print((r - l + 1 ) - max_set + " " );
}
}
public static void main(String args[])
{
int [][]queries
= { { 1 , 5 }, { 3 , 4 }, { 5 , 10 }, { 10 , 15 } };
solve_queries(queries);
}
}
|
Python3
def solve_queries (q):
for i in range ( len (q)):
l = q[i][ 0 ]
r = q[i][ 1 ]
max_set = 0
for i in range ( 31 ):
cnt = 0
for j in range (l, r + 1 ):
if (( 1 << i) & j):
cnt + = 1
max_set = max (max_set, cnt)
print (f "{(r - l + 1) - max_set} " , end = " " )
queries = [[ 1 , 5 ], [ 3 , 4 ], [ 5 , 10 ], [ 10 , 15 ]]
solve_queries(queries)
|
C#
using System;
public class GFG{
static void solve_queries( int [,] q)
{
for ( int i = 0; i < 4; i++) {
int l = q[i, 0];
int r = q[i, 1];
int max_set = 0;
for ( int k = 0; k < 31; k++) {
int cnt = 0;
for ( int j = l; j <= r; j++) {
if (((1 << k) & j) != 0) {
cnt++;
}
}
max_set = Math.Max(max_set, cnt);
}
Console.Write((r - l + 1) - max_set + " " );
}
}
static public void Main()
{
int [,] queries = new int [4,2] { { 1, 5 }, { 3, 4 }, { 5, 10 }, { 10, 15 } };
solve_queries(queries);
}
}
|
Javascript
<script>
const solve_queries = (q) => {
for (let i = 0; i < q.length; i++)
{
let l = q[i][0];
let r = q[i][1];
let max_set = 0;
for (let i = 0; i < 31; i++)
{
let cnt = 0;
for (let j = l; j <= r; j++)
{
if ((1 << i) & j)
{
cnt++;
}
}
max_set = Math.max(max_set, cnt);
}
document.write(`${(r - l + 1) - max_set} `);
}
}
let queries = [ [ 1, 5 ], [ 3, 4 ],
[ 5, 10 ], [ 10, 15 ] ];
solve_queries(queries);
</script>
|
Time Complexity: O (31 * Q * n ) where n is the length of the maximum range.
Auxiliary Space: O(1)
Efficient Approach: This approach is based on Dynamic programming and prefix sum technique. This can be done by storing the count of total set bits till that range in a using dp[] array at each position of 31 bits. Here the state of dp[i][j] means that the total set bits of jth bit position till i from [1, i]. Follow these steps to solve the above problem:
- Make a function call to count_set_bits() to precalculate the dp[][] array using prefix sum.
- Now iterate through the queries and assign l = q[i][0], r = q[i][1].
- Initialize max_set = INT_MIN to store the count of the max count of elements in the range having the j-th bit set.
- Iterate through the bits from [0, 30].
- Count the number of elements having j-th bit set by total_set = (dp[r][j] – dp[l – 1][j]).
- Store the max count of elements having j-th bit set by taking max(max_set, total_set).
- Print the minimum removals required by subtracting max_set from the total length (r-l+1).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int dp[200005][31];
void count_set_bits()
{
int N = 2e5 + 5;
for ( int i = 1; i < N; i++) {
for ( int j = 0; j <= 30; j++) {
if (i & (1 << j))
dp[i][j] = 1;
dp[i][j] += dp[i - 1][j];
}
}
}
void solve_queries(vector<vector< int > > q)
{
count_set_bits();
for ( int i = 0; i < q.size(); i++) {
int l = q[i][0];
int r = q[i][1];
int max_set = INT_MIN;
for ( int j = 0; j <= 30; j++) {
int total_set = (dp[r][j] - dp[l - 1][j]);
max_set = max(max_set, total_set);
}
cout << (r - l + 1) - max_set << " " ;
}
}
int main()
{
vector<vector< int > > queries
= { { 1, 5 }, { 3, 4 }, { 5, 10 }, { 10, 15 } };
solve_queries(queries);
return 0;
}
|
Java
import java.io.*;
class GFG
{
public static int dp[][] = new int [ 200005 ][ 31 ];
public static void count_set_bits()
{
int N = 200005 ;
for ( int i = 1 ; i < N; i++)
{
for ( int j = 0 ; j <= 30 ; j++)
{
if ((i & ( 1 << j))!= 0 )
dp[i][j] = 1 ;
dp[i][j] += dp[i - 1 ][j];
}
}
}
public static void solve_queries( int [][] q)
{
count_set_bits();
for ( int i = 0 ; i < q.length; i++) {
int l = q[i][ 0 ];
int r = q[i][ 1 ];
int max_set = Integer.MIN_VALUE;
for ( int j = 0 ; j <= 30 ; j++) {
int total_set = (dp[r][j] - dp[l - 1 ][j]);
max_set = Math.max(max_set, total_set);
}
System.out.print((r - l + 1 ) - max_set + " " );
}
}
public static void main (String[] args)
{
int [][] queries = new int [][]
{
new int [] { 1 , 5 },
new int [] { 3 , 4 },
new int [] { 5 , 10 },
new int [] { 10 , 15 }
};
solve_queries(queries);
}
}
|
Python3
dp = [[ 0 for i in range ( 31 )] for j in range ( 200005 )]
def count_set_bits():
N = 200005
for i in range ( 1 , N):
for j in range ( 31 ):
if (i & ( 1 << j)):
dp[i][j] = 1
dp[i][j] + = dp[i - 1 ][j]
def solve_queries(q):
count_set_bits()
for i in range ( len (q)):
l = q[i][ 0 ]
r = q[i][ 1 ]
max_set = - 2 * * 32
for j in range ( 31 ):
total_set = (dp[r][j] - dp[l - 1 ][j])
max_set = max (max_set, total_set)
print ((r - l + 1 ) - max_set, end = " " )
queries = [[ 1 , 5 ], [ 3 , 4 ], [ 5 , 10 ], [ 10 , 15 ]]
solve_queries(queries)
|
C#
using System;
public class GFG{
public static int [,] dp = new int [200005,31];
public static void count_set_bits()
{
int N = 200005;
for ( int i = 1; i < N; i++)
{
for ( int j = 0; j <= 30; j++)
{
if ((i & (1 << j))!=0)
dp[i,j] = 1;
dp[i,j] += dp[i - 1,j];
}
}
}
public static void solve_queries( int [][] q)
{
count_set_bits();
for ( int i = 0; i < q.Length; i++) {
int l = q[i][0];
int r = q[i][1];
int max_set = Int32.MinValue;
for ( int j = 0; j <= 30; j++) {
int total_set = (dp[r,j] - dp[l - 1,j]);
max_set = Math.Max(max_set, total_set);
}
Console.Write((r - l + 1) - max_set + " " );
}
}
static public void Main ()
{
int [][] queries = new int [][]
{
new int [] { 1, 5 },
new int [] { 3, 4 },
new int [] { 5, 10 },
new int [] { 10, 15 }
};
solve_queries(queries);
}
}
|
Javascript
<script>
let dp = new Array(200005)
for (let i = 0; i < 200005; i++){
dp[i] = new Array(31).fill(0)
}
function count_set_bits(){
let N = 200005
for (let i = 1; i < N; i++){
for (let j = 0; j < 31; j++){
if (i & (1 << j))
dp[i][j] = 1
dp[i][j] += dp[i - 1][j]
}
}
}
function solve_queries(q){
count_set_bits()
for (let i = 0; i < q.length; i++){
let l = q[i][0]
let r = q[i][1]
let max_set = Number.MIN_VALUE
for (let j = 0; j < 31; j++){
let total_set = (dp[r][j] - dp[l - 1][j])
max_set = Math.max(max_set, total_set)
}
document.write((r - l + 1) - max_set, " " )
}
}
let queries = [[1, 5], [3, 4], [5, 10], [10, 15]]
solve_queries(queries)
</script>
|
Time Complexity: O(31 * (Q+n))
Auxiliary Space: O(n)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...