📜  范围查询设置位的数量

📅  最后修改于: 2021-04-26 05:23:13             🧑  作者: Mango

给定正整数数组和包含两个整数的q查询,L&R。任务是查找给定范围内的置位位数。
先决条件:按位黑客

例子 :

Input :  Arr[] = { 1, 5, 6, 10, 9, 4 }
         Query : 2 
         L  &  R
         1     5
         2     4
Output : 9
         6

Input : Arr[] = { 1, 10, 5, 2, 8, 11, 15 }
        Query : 2
        L  &  R
        2     4
        1     5
Output :  4
          9

解决此问题的简单方法是运行一个从L到R的循环,并对范围中的设置位数进行计数。此解决方案为每个查询取O(nlog(s))(其中s是位大小)。

高效的解决方案基于这样一个事实:如果我们将所有数字的所有设置位的计数存储在“ BitCounts”数组中,那么我们将在O(1)时间内回答每个查询。因此,开始遍历数组的元素并计算每个元素的设置位并存储在数组中。现在,找到该数组的累加和。该数组将有助于回答查询。

BitCount[] that will store the count of set bits
in a number. 

Run a Loop from 0 to 31 "for 32 bits size integer "       
-> mark elements with i'th bit set     

Run an inner Loop from 0 to size of Array "Arr"  
     -> Check whether the current bit is set or not 
     -> if it's set then mark it.
          long  temp = arr[j] >> i;
             if (temp %2 != 0)
                 BitCount[j] += 1

以下是上述想法的实现。

C++
// C++ program to Range query for
// Count number of set bits
#include 
using namespace std;
 
// 2-D array that will stored the count
// of bits set in element of array
int BitCount[10000] = { 0 };
 
// Function store the set bit
// count in BitCount Array
void fillSetBitsMatrix(int arr[], int n)
{
 
    // traverse over all bits
    for (int i = 0; i < 32; i++) {
 
        // mark elements with i'th bit set
        for (int j = 0; j < n; j++) {
 
            // Check whether the current bit is
            // set or not if it's set then mark it.
            long temp = arr[j] >> i;
            if (temp % 2 != 0)
                BitCount[j] += 1;
        }
    }
 
    // store cumulative sum of bits
    for (int i = 1; i < n; i++)
        BitCount[i] += BitCount[i - 1];
}
 
// Function to process queries
void Query(int Q[][2], int q)
{
    for (int i = 0; i < q; i++)
        cout << (BitCount[Q[i][1]] -
                 BitCount[Q[i][0] - 1]) << endl;
}
 
// Driver Code
int main()
{
    int Arr[] = { 1, 5, 6, 10, 9, 4, 67 };
    int n = sizeof(Arr) / sizeof(Arr[0]);
 
    fillSetBitsMatrix(Arr, n);
 
    int q = 2;
    int Q[2][2] = { { 1, 5 }, { 2, 6 } };
 
    Query(Q, q);
 
    return 0;
}


Java
// Java program to Range query for
// Count number of set bits
import java.io.*;
 
class GFG {
 
    // 2-D array that will stored the count
    // of bits set in element of array
    static int BitCount[] = new int[10000];
     
    // Function store the set bit
    // count in BitCount Array
    static void fillSetBitsMatrix(int arr[], int n)
    {
     
        // traverse over all bits
        for (int i = 0; i < 32; i++) {
     
            // mark elements with i'th bit set
            for (int j = 0; j < n; j++) {
     
                // Check whether the current
                // bit is set or not if it's
                // set then mark it.
                long temp = arr[j] >> i;
                if (temp % 2 != 0)
                    BitCount[j] += 1;
            }
        }
     
        // store cumulative sum of bits
        for (int i = 1; i < n; i++)
            BitCount[i] += BitCount[i - 1];
    }
     
    // Function to process queries
    static void Query(int Q[][], int q)
    {
        for (int i = 0; i < q; i++)
            System.out.println( (BitCount[Q[i][1]]
                        - BitCount[Q[i][0] - 1]));
    }
     
    // Driver Code
    public static void main (String[] args)
    {
        int Arr[] = { 1, 5, 6, 10, 9, 4, 67 };
        int n = Arr.length;
     
        fillSetBitsMatrix(Arr, n);
     
        int q = 2;
        int Q[][] = { { 1, 5 }, { 2, 6 } };
     
        Query(Q, q);
    }
}
 
// This code is contributed by anuj_67.


Python3
# Python3 program to Range query for
# Count number of set bits
 
# 2-D array that will stored the count
# of bits set in element of array
BitCount = [0] * 10000
 
# Function store the set bit
# count in BitCount Array
def fillSetBitsmatrix(arr: list, n: int):
    global BitCount
 
    # traverse over all bits
    for i in range(32):
 
        # mark elements with i'th bit set
        for j in range(n):
 
            # Check whether the current bit is
            # set or not if it's set then mark it.
            temp = arr[j] >> i
            if temp % 2 != 0:
                BitCount[j] += 1
 
    # store cumulative sum of bits
    for i in range(1, n):
        BitCount[i] += BitCount[i - 1]
 
# Function to process queries
def Query(Q: list, q: int):
    for i in range(q):
        print(BitCount[Q[i][1]] - BitCount[Q[i][0] - 1])
 
# Driver Code
if __name__ == "__main__":
 
    Arr = [1, 5, 6, 10, 9, 4, 67]
    n = len(Arr)
 
    fillSetBitsmatrix(Arr, n)
 
    q = 2
    Q = [(1, 5), (2, 6)]
    Query(Q, q)
 
# This code is contributed by
# sanjeev2552


C#
// C# program to Range query for
// Count number of set bits
using System;
 
class GFG {
 
    // 2-D array that will stored the count
    // of bits set in element of array
    static int []BitCount = new int[10000];
     
    // Function store the set bit
    // count in BitCount Array
    static void fillSetBitsMatrix(int []arr, int n)
    {
     
        // traverse over all bits
        for (int i = 0; i < 32; i++) {
     
            // mark elements with i'th bit set
            for (int j = 0; j < n; j++) {
     
                // Check whether the current
                // bit is set or not if it's
                // set then mark it.
                long temp = arr[j] >> i;
                if (temp % 2 != 0)
                    BitCount[j] += 1;
            }
        }
     
        // store cumulative sum of bits
        for (int i = 1; i < n; i++)
            BitCount[i] += BitCount[i - 1];
    }
     
    // Function to process queries
    static void Query(int [,]Q, int q)
    {
        for (int i = 0; i < q; i++)
            Console.WriteLine( (BitCount[Q[i,1]]
                        - BitCount[Q[i,0] - 1]));
    }
     
    // Driver Code
    public static void Main ()
    {
        int []Arr = { 1, 5, 6, 10, 9, 4, 67 };
        int n = Arr.Length;
     
        fillSetBitsMatrix(Arr, n);
     
        int q = 2;
        int [,]Q = { { 1, 5 }, { 2, 6 } };
     
        Query(Q, q);
    }
}
 
// This code is contributed by anuj_67.


Javascript


输出:
9
10

时间复杂度:每个查询为O(1)。