📌  相关文章
📜  从具有单个设置位的给定范围计算数组元素的查询

📅  最后修改于: 2021-09-06 11:34:04             🧑  作者: Mango

给定一个由正整数组成的数组arr[]和一个由查询组成的数组Q[][] ,每个i查询的任务是计算范围[Q[i][0], Q[i] 中的数组元素[1]]只有一个设置位。

例子:

朴素的方法:对于每个查询,最简单的方法是迭代范围[l, r]并使用 Brian Kernighan 算法计算只有一个设置位的数组元素的数量。

时间复杂度:O(Q * N*logN)
辅助空间: O(1)

高效方法:按照以下步骤优化上述方法:

  • 初始化一个前缀和数组以存储只有一个设置位的元素数量。
  • i 个索引存储数组元素的计数,只有一个设置位,直到第 i索引。
  • 对于每个查询(i, j) ,返回pre[j] – pre[i – 1] ,即(包含-排除原则)。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to check whether
// only one bit is set or not
int check(int x)
{
    if (((x) & (x - 1)) == 0)
        return 1;
    return 0;
}
 
// Function to perform Range-query
int query(int l, int r, int pre[])
{
    if (l == 0)
        return pre[r];
    else
        return pre[r] - pre[l - 1];
}
 
// Function to count array elements with a
// single set bit for each range in a query
void countInRange(int arr[], int N,
                  vector > queries, int Q)
{
    // Initialize array for Prefix sum
    int pre[N] = { 0 };
    pre[0] = check(arr[0]);
 
    for (int i = 1; i < N; i++) {
        pre[i] = pre[i - 1] + check(arr[i]);
    }
 
    int c = 0;
    while (Q--) {
        int l = queries.first;
        int r = queries.second;
        c++;
        cout << query(l, r, pre) << ' ';
    }
}
 
// Driver Code
int main()
{
    // Given array
    int arr[] = { 12, 11, 16, 8, 2, 5, 1, 3, 256, 1 };
 
    // Size of the array
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Given queries
    vector > queries
        = { { 0, 9 }, { 4, 9 } };
 
    // Size of queries array
    int Q = queries.size();
 
    countInRange(arr, N, queries, Q);
 
    return 0;
}


Java
// JAVA program for the above approach
import java.util.*;
import java.io.*;
import java.math.*;
public class GFG
{
 
  // Function to check whether
  // only one bit is set or not
  static int check(int x)
  {
    if (((x) & (x - 1)) == 0)
      return 1;
 
    return 0;
  }
 
  // Function to perform Range-query
  static int query(int l, int r, int[] pre)
  {
    if (l == 0)
      return pre[r];
    else
      return pre[r] - pre[l - 1];
  }
 
  // Function to count array elements with a
  // single set bit for each range in a query
  static void countInRange(int[] arr, int N,  ArrayList queries,
                           int Q)
  {
 
    // Initialize array for Prefix sum
    int[] pre = new int[N];
    pre[0] = check(arr[0]);
    for(int i = 1; i < N; i++)
    {
      pre[i] = pre[i - 1] + check(arr[i]);
    }  
    int c = 0;
    int q = 0;   
    while (q < Q)
    {
      int l = queries.get(q).item1;
      int r = queries.get(q).item2;
      c++;
      q++;
      System.out.print(query(l, r, pre) + " ");
    }
  }
 
  // A Pair class for handling queries in JAVA
  // As, there is no in-built function of Tuple
  static class Pair
  {
    int item1, item2;
    Pair(int item1, int item2)
    {
      this.item1 = item1;
      this.item2 = item2;
    }
  }
 
  // Driver code
  public static void main(String args[])
  {
 
    // Given array
    int[] arr = { 12, 11, 16, 8, 2,
                 5, 1, 3, 256, 1 };
 
    // Size of the array
    int N = arr.length;
 
    // Given queries
    ArrayList queries = new ArrayList();
    queries.add(new Pair(4,9));
    queries.add(new Pair(0,9));
 
    // Size of queries array
    int Q = queries.size();    
    countInRange(arr, N, queries, Q);
  }
}
 
// This code is contributed by jyoti369


Python3
# Python 3 program for the above approach
 
# Function to check whether
# only one bit is set or not
def check(x):
    if (((x) & (x - 1)) == 0):
        return 1
    return 0
 
# Function to perform Range-query
def query(l, r, pre):
    if (l == 0):
        return pre[r]
    else:
        return pre[r] - pre[l - 1]
 
# Function to count array elements with a
# single set bit for each range in a query
def countInRange(arr,  N, queries, Q):
 
    # Initialize array for Prefix sum
    pre = [0] * N
    pre[0] = check(arr[0])
    for i in range(1, N):
        pre[i] = pre[i - 1] + check(arr[i])
    c = 0
    while (Q > 0):
        l = queries[0]
        r = queries[1]
        c += 1
        print(query(l, r, pre), end=" ")
        Q -= 1
 
 
# Driver Code
if __name__ == "__main__":
 
    # Given array
    arr = [12, 11, 16, 8, 2, 5, 1, 3, 256, 1]
 
    # Size of the array
    N = len(arr)
 
    # Given queries
    queries = [[0, 9], [4, 9]]
 
    # Size of queries array
    Q = len(queries)
 
    countInRange(arr, N, queries, Q)
 
    # this code is contributed by chitranayal.


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
     
// Function to check whether
// only one bit is set or not
static int check(int x)
{
    if (((x) & (x - 1)) == 0)
        return 1;
         
    return 0;
}
   
// Function to perform Range-query
static int query(int l, int r, int[] pre)
{
    if (l == 0)
        return pre[r];
    else
        return pre[r] - pre[l - 1];
}
 
// Function to count array elements with a
// single set bit for each range in a query
static void countInRange(int[] arr, int N,
                         List> queries,
                         int Q)
{
     
    // Initialize array for Prefix sum
    int[] pre = new int[N];
    pre[0] = check(arr[0]);
   
    for(int i = 1; i < N; i++)
    {
        pre[i] = pre[i - 1] + check(arr[i]);
    }
   
    int c = 0;
    int q = 0;
     
    while (q < Q)
    {
        int l = queries[q].Item1;
        int r = queries[q].Item2;
        c++;
        q++;
        Console.Write(query(l, r, pre) + " ");
    }
}
 
// Driver code
static void Main()
{
     
    // Given array
    int[] arr = { 12, 11, 16, 8, 2,
                  5, 1, 3, 256, 1 };
     
    // Size of the array
    int N = arr.Length;
     
    // Given queries
    List> queries = new List>();
    queries.Add(new Tuple(0, 9));
    queries.Add(new Tuple(4, 9));
     
    // Size of queries array
    int Q = queries.Count;
     
    countInRange(arr, N, queries, Q);
}
}
 
// This code is contributed by divyeshrabadiya07


Javascript


输出:
6 4

时间复杂度: O(N*log(max(arr[i])))
辅助空间: O(N)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live