对于给定的范围查询,使按位与非零的范围内的最小删除
给定一个Q范围查询的数组queries[][] ,任务是从范围[l, r]中找到最小移除,使得范围的按位与是非零值。
例子:
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
朴素的方法:这可以通过遍历每个范围并检查具有公共设置位的范围内元素的最大计数并将其从元素的总计数中删除来解决,即(r – l + 1) 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function the find the minimum removals
// to make the bitwise AND of range non-zero
void solve_queries(vector > q)
{
for (int i = 0; i < q.size(); i++) {
int l = q[i][0];
int r = q[i][1];
// Initialize the max_set to check
// what count of set bit majority of
// numbers in the range was set
int max_set = 0;
for (int i = 0; i < 31; i++) {
int cnt = 0;
for (int j = l; j <= r; j++) {
// Check if is set
if ((1 << i) & j) {
cnt++;
}
}
max_set = max(max_set, cnt);
}
// Total length of range - count of
// max numbers having 1 bit set in range
cout << (r - l + 1) - max_set << " ";
}
}
// Driver Code
int main()
{
// Initialize the queries
vector > queries
= { { 1, 5 }, { 3, 4 }, { 5, 10 }, { 10, 15 } };
solve_queries(queries);
return 0;
}
Java
// Java code to implement the above approach
import java.util.*;
public class GFG
{
// Function the find the minimum removals
// to make the bitwise AND of range non-zero
static void solve_queries(int [][]q)
{
for (int i = 0; i < q.length; i++) {
int l = q[i][0];
int r = q[i][1];
// Initialize the max_set to check
// what count of set bit majority of
// numbers in the range was set
int max_set = 0;
for (int k = 0; k < 31; k++) {
int cnt = 0;
for (int j = l; j <= r; j++) {
// Check if is set
if (((1 << k) & j) != 0) {
cnt++;
}
}
max_set = Math. max(max_set, cnt);
}
// Total length of range - count of
// max numbers having 1 bit set in range
System.out.print((r - l + 1) - max_set + " ");
}
}
// Driver code
public static void main(String args[])
{
// Initialize the queries
int [][]queries
= { { 1, 5 }, { 3, 4 }, { 5, 10 }, { 10, 15 } };
solve_queries(queries);
}
}
// This code is contributed by Samim Hossain Mondal.
Python3
# Python program for the above approach
# Function the find the minimum removals
# to make the bitwise AND of range non-zero
def solve_queries (q):
for i in range(len(q)):
l = q[i][0]
r = q[i][1]
# Initialize the max_set to check
# what count of set bit majority of
# numbers in the range was set
max_set = 0
for i in range(31):
cnt = 0
for j in range(l, r + 1):
# Check if is set
if ((1 << i) & j):
cnt += 1
max_set = max(max_set, cnt)
# Total length of range - count of
# max numbers having 1 bit set in range
print(f"{(r - l + 1) - max_set} ", end=" ")
# Driver Code
# Initialize the queries
queries = [[1, 5], [3, 4], [5, 10], [10, 15]]
solve_queries(queries)
# This code is contributed by gfgking
C#
// C# code to implement the above approach
using System;
public class GFG{
// Function the find the minimum removals
// to make the bitwise AND of range non-zero
static void solve_queries(int[,] q)
{
for (int i = 0; i < 4; i++) {
int l = q[i, 0];
int r = q[i, 1];
// Initialize the max_set to check
// what count of set bit majority of
// numbers in the range was set
int max_set = 0;
for (int k = 0; k < 31; k++) {
int cnt = 0;
for (int j = l; j <= r; j++) {
// Check if is set
if (((1 << k) & j) != 0) {
cnt++;
}
}
max_set = Math.Max(max_set, cnt);
}
// Total length of range - count of
// max numbers having 1 bit set in range
Console.Write((r - l + 1) - max_set + " ");
}
}
// Driver code
static public void Main()
{
// Initialize the queries
int[,] queries = new int[4,2] { { 1, 5 }, { 3, 4 }, { 5, 10 }, { 10, 15 } };
solve_queries(queries);
}
}
// This code is contributed by Shubham Singh
Javascript
C++
// C++ program for the above approach
#include
using namespace std;
int dp[200005][31];
// Function to build the dp array
// which stores the set bits for
// each bit position till 200005.
void count_set_bits()
{
int N = 2e5 + 5;
for (int i = 1; i < N; i++) {
for (int j = 0; j <= 30; j++) {
// If j th bit is set assign
// dp[i][j] =1 where dp[i][j] means
// number of jth bits set till i
if (i & (1 << j))
dp[i][j] = 1;
// Calculate the prefix sum
dp[i][j] += dp[i - 1][j];
}
}
}
// Function to solve the queries
void solve_queries(vector > q)
{
// Call the function to
// precalculate the dp array
count_set_bits();
for (int i = 0; i < q.size(); i++) {
int l = q[i][0];
int r = q[i][1];
// Initialize the max_set = INT_MIN to
// check what count of set bit
// majority of numbers in the range was set
int max_set = INT_MIN;
// For each bit check the
// maximum numbers in the range
// having the j th bit set
for (int j = 0; j <= 30; j++) {
int total_set = (dp[r][j] - dp[l - 1][j]);
max_set = max(max_set, total_set);
}
// Total length of range - count of max
// numbers having 1 bit set in the range
cout << (r - l + 1) - max_set << " ";
}
}
// Driver Code
int main()
{
// Initialize the queries
vector > queries
= { { 1, 5 }, { 3, 4 }, { 5, 10 }, { 10, 15 } };
solve_queries(queries);
return 0;
}
Java
// Java code to implement the above approach
import java.io.*;
class GFG
{
public static int dp[][] = new int[200005][31];
// Function to build the dp array
// which stores the set bits for
// each bit position till 200005.
public static void count_set_bits()
{
int N = 200005;
for (int i = 1; i < N; i++)
{
for (int j = 0; j <= 30; j++)
{
// If j th bit is set assign
// dp[i][j] =1 where dp[i][j] means
// number of jth bits set till i
if ((i & (1 << j))!=0)
dp[i][j] = 1;
// Calculate the prefix sum
dp[i][j] += dp[i - 1][j];
}
}
}
// Function to solv e the queries
public static void solve_queries(int[][] q)
{
// Call the function to
// precalculate the dp array
count_set_bits();
for (int i = 0; i < q.length; i++) {
int l = q[i][0];
int r = q[i][1];
// Initialize the max_set = INT_MIN to
// check what count of set bit
// majority of numbers in the range was set
int max_set = Integer.MIN_VALUE;
// For each bit check the
// maximum numbers in the range
// having the j th bit set
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);
}
// Total length of range - count of max
// numbers having 1 bit set in the range
System.out.print((r - l + 1) - max_set + " ");
}
}
// Driver Code
public static void main (String[] args)
{
// Initialize the queries
int[][] queries = new int[][]
{
new int[] { 1, 5 },
new int[] { 3, 4 },
new int[] { 5, 10 },
new int[] { 10, 15 }
};
solve_queries(queries);
}
}
// This code is contributed by Shubham Singh
Python3
# Python program for the above approach
dp = [[0 for i in range(31)] for j in range(200005)]
# Function to build the dp array
# which stores the set bits for
# each bit position till 200005.
def count_set_bits():
N = 200005
for i in range(1, N):
for j in range(31):
# If j th bit is set assign
# dp[i][j] =1 where dp[i][j] means
# number of jth bits set till i
if (i & (1 << j)):
dp[i][j] = 1
# Calculate the prefix sum
dp[i][j] += dp[i - 1][j]
# Function to solve the queries
def solve_queries(q):
# Call the function to
# precalculate the dp array
count_set_bits()
for i in range(len(q)):
l = q[i][0]
r = q[i][1]
# Initialize the max_set = INT_MIN to
# check what count of set bit
# majority of numbers in the range was set
max_set = -2**32
# For each bit check the
# maximum numbers in the range
# having the j th bit set
for j in range(31):
total_set = (dp[r][j] - dp[l - 1][j])
max_set = max(max_set, total_set)
# Total length of range - count of max
# numbers having 1 bit set in the range
print((r - l + 1) - max_set, end=" ")
# Driver Code
# Initialize the queries
queries = [[1, 5], [3, 4], [5, 10], [10, 15]]
solve_queries(queries)
# This code is contributed by Shubham Singh
C#
// C# code to implement the above approach
using System;
public class GFG{
public static int[,] dp = new int[200005,31];
// Function to build the dp array
// which stores the set bits for
// each bit position till 200005.
public static void count_set_bits()
{
int N = 200005;
for (int i = 1; i < N; i++)
{
for (int j = 0; j <= 30; j++)
{
// If j th bit is set assign
// dp[i,j] =1 where dp[i,j] means
// number of jth bits set till i
if ((i & (1 << j))!=0)
dp[i,j] = 1;
// Calculate the prefix sum
dp[i,j] += dp[i - 1,j];
}
}
}
// Function to solv e the queries
public static void solve_queries(int[][] q)
{
// Call the function to
// precalculate the dp array
count_set_bits();
for (int i = 0; i < q.Length; i++) {
int l = q[i][0];
int r = q[i][1];
// Initialize the max_set = INT_MIN to
// check what count of set bit
// majority of numbers in the range was set
int max_set = Int32.MinValue;
// For each bit check the
// maximum numbers in the range
// having the j th bit set
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);
}
// Total length of range - count of max
// numbers having 1 bit set in the range
Console.Write((r - l + 1) - max_set + " ");
}
}
// Driver Code
static public void Main ()
{
// Initialize the queries
int[][] queries = new int[][]
{
new int[] { 1, 5 },
new int[] { 3, 4 },
new int[] { 5, 10 },
new int[] { 10, 15 }
};
solve_queries(queries);
}
}
// This code is contributed by Shubham Singh
2 1 3 0
时间复杂度: O (31 * Q * n ) 其中 n 是最大范围的长度。
辅助空间: O(1)
高效方法:这种方法基于动态编程和前缀和技术。这可以通过在 31 位的每个位置使用dp[]数组存储到该范围的总设置位的计数来完成。这里dp[i][j]的状态表示从[1, i]到i的第 j 位位置的总设置位。按照以下步骤解决上述问题:
- 对count_set_bits()进行函数调用以使用前缀 sum预先计算dp[][]数组。
- 现在遍历查询并分配l = q[i][0], r = q[i][1] 。
- 初始化max_set = INT_MIN以存储设置了第j位的范围内元素的最大计数的计数。
- 遍历[0, 30]中的位。
- 计算由total_set = (dp[r][j] – dp[l – 1][j])设置的第 j位元素的数量。
- 通过采用max(max_set, total_set)存储具有第 j位设置的元素的最大计数。
- 通过从总长度(r-l+1)中减去max_set打印所需的最小移除量。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
int dp[200005][31];
// Function to build the dp array
// which stores the set bits for
// each bit position till 200005.
void count_set_bits()
{
int N = 2e5 + 5;
for (int i = 1; i < N; i++) {
for (int j = 0; j <= 30; j++) {
// If j th bit is set assign
// dp[i][j] =1 where dp[i][j] means
// number of jth bits set till i
if (i & (1 << j))
dp[i][j] = 1;
// Calculate the prefix sum
dp[i][j] += dp[i - 1][j];
}
}
}
// Function to solve the queries
void solve_queries(vector > q)
{
// Call the function to
// precalculate the dp array
count_set_bits();
for (int i = 0; i < q.size(); i++) {
int l = q[i][0];
int r = q[i][1];
// Initialize the max_set = INT_MIN to
// check what count of set bit
// majority of numbers in the range was set
int max_set = INT_MIN;
// For each bit check the
// maximum numbers in the range
// having the j th bit set
for (int j = 0; j <= 30; j++) {
int total_set = (dp[r][j] - dp[l - 1][j]);
max_set = max(max_set, total_set);
}
// Total length of range - count of max
// numbers having 1 bit set in the range
cout << (r - l + 1) - max_set << " ";
}
}
// Driver Code
int main()
{
// Initialize the queries
vector > queries
= { { 1, 5 }, { 3, 4 }, { 5, 10 }, { 10, 15 } };
solve_queries(queries);
return 0;
}
Java
// Java code to implement the above approach
import java.io.*;
class GFG
{
public static int dp[][] = new int[200005][31];
// Function to build the dp array
// which stores the set bits for
// each bit position till 200005.
public static void count_set_bits()
{
int N = 200005;
for (int i = 1; i < N; i++)
{
for (int j = 0; j <= 30; j++)
{
// If j th bit is set assign
// dp[i][j] =1 where dp[i][j] means
// number of jth bits set till i
if ((i & (1 << j))!=0)
dp[i][j] = 1;
// Calculate the prefix sum
dp[i][j] += dp[i - 1][j];
}
}
}
// Function to solv e the queries
public static void solve_queries(int[][] q)
{
// Call the function to
// precalculate the dp array
count_set_bits();
for (int i = 0; i < q.length; i++) {
int l = q[i][0];
int r = q[i][1];
// Initialize the max_set = INT_MIN to
// check what count of set bit
// majority of numbers in the range was set
int max_set = Integer.MIN_VALUE;
// For each bit check the
// maximum numbers in the range
// having the j th bit set
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);
}
// Total length of range - count of max
// numbers having 1 bit set in the range
System.out.print((r - l + 1) - max_set + " ");
}
}
// Driver Code
public static void main (String[] args)
{
// Initialize the queries
int[][] queries = new int[][]
{
new int[] { 1, 5 },
new int[] { 3, 4 },
new int[] { 5, 10 },
new int[] { 10, 15 }
};
solve_queries(queries);
}
}
// This code is contributed by Shubham Singh
Python3
# Python program for the above approach
dp = [[0 for i in range(31)] for j in range(200005)]
# Function to build the dp array
# which stores the set bits for
# each bit position till 200005.
def count_set_bits():
N = 200005
for i in range(1, N):
for j in range(31):
# If j th bit is set assign
# dp[i][j] =1 where dp[i][j] means
# number of jth bits set till i
if (i & (1 << j)):
dp[i][j] = 1
# Calculate the prefix sum
dp[i][j] += dp[i - 1][j]
# Function to solve the queries
def solve_queries(q):
# Call the function to
# precalculate the dp array
count_set_bits()
for i in range(len(q)):
l = q[i][0]
r = q[i][1]
# Initialize the max_set = INT_MIN to
# check what count of set bit
# majority of numbers in the range was set
max_set = -2**32
# For each bit check the
# maximum numbers in the range
# having the j th bit set
for j in range(31):
total_set = (dp[r][j] - dp[l - 1][j])
max_set = max(max_set, total_set)
# Total length of range - count of max
# numbers having 1 bit set in the range
print((r - l + 1) - max_set, end=" ")
# Driver Code
# Initialize the queries
queries = [[1, 5], [3, 4], [5, 10], [10, 15]]
solve_queries(queries)
# This code is contributed by Shubham Singh
C#
// C# code to implement the above approach
using System;
public class GFG{
public static int[,] dp = new int[200005,31];
// Function to build the dp array
// which stores the set bits for
// each bit position till 200005.
public static void count_set_bits()
{
int N = 200005;
for (int i = 1; i < N; i++)
{
for (int j = 0; j <= 30; j++)
{
// If j th bit is set assign
// dp[i,j] =1 where dp[i,j] means
// number of jth bits set till i
if ((i & (1 << j))!=0)
dp[i,j] = 1;
// Calculate the prefix sum
dp[i,j] += dp[i - 1,j];
}
}
}
// Function to solv e the queries
public static void solve_queries(int[][] q)
{
// Call the function to
// precalculate the dp array
count_set_bits();
for (int i = 0; i < q.Length; i++) {
int l = q[i][0];
int r = q[i][1];
// Initialize the max_set = INT_MIN to
// check what count of set bit
// majority of numbers in the range was set
int max_set = Int32.MinValue;
// For each bit check the
// maximum numbers in the range
// having the j th bit set
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);
}
// Total length of range - count of max
// numbers having 1 bit set in the range
Console.Write((r - l + 1) - max_set + " ");
}
}
// Driver Code
static public void Main ()
{
// Initialize the queries
int[][] queries = new int[][]
{
new int[] { 1, 5 },
new int[] { 3, 4 },
new int[] { 5, 10 },
new int[] { 10, 15 }
};
solve_queries(queries);
}
}
// This code is contributed by Shubham Singh
2 1 3 0
时间复杂度: O(31 * Q)
辅助空间: O(n)