📌  相关文章
📜  计数范围 [L, R] 中只有三个设置位的数字

📅  最后修改于: 2022-05-13 01:56:07.534000             🧑  作者: Mango

计数范围 [L, R] 中只有三个设置位的数字

给定一个N对数组arr[] ,其中每个数组元素表示{L, R} 形式的查询,任务是找到[L, R]范围内的数字的计数,只有 3 个集合位对于每个查询{L, R}。

例子:

方法:解决这个问题的思路是先做一个预计算,把所有只有3位的数字存储在[1, 10 18 ]范围内,然后用二分查找找到L的下界和上界的位置的R并返回答案,因为存在差异。请按照以下步骤解决给定的问题:

  • 初始化一个向量,比如V ,以存储范围[1, 10 18 ]中的所有数字,并且只设置了三位。
  • 使用变量i, j迭代由关系[0, 63]×[0, 63]×[0, 63]形成的每个三元组,k并执行以下步骤:
    • 如果i、jk不同,则使用 i、第j 位k位设置,如果数量小于10 18推动向量V中的数字。
  • 按升序对向量 V 进行排序。
  • 使用变量i遍历数组arr[],并执行以下步骤:
    • 将查询的边界分别存储在变量中,例如LR
    • 求向量VL的下界和R的上界的位置。
    • 打印R的上限位置和L的下限位置之间的差,作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
  
// Function to precompute
void precompute(vector& v)
{
    // Iterate over the range [0, 64]
    for (long long i = 0; i < 64; i++) {
        // Iterate over the range [0, 64]
        for (long long j = i + 1; j < 64; j++) {
            // Iterate over the range [0, 64]
            for (long long k = j + 1; k < 64; k++) {
  
                // Stores the number with set bits
                // i, j, and k
                long long int x
                    = (1LL << i) | (1LL << j) | (1LL << k);
  
                // Check if the number is less
                // than 1e18
                if (x <= 1e18 && x > 0)
                    v.push_back(x);
            }
        }
    }
  
    // Sort the computed vector
    sort(v.begin(), v.end());
}
  
// Function to count number in the range
// [l, r] having three set bits
long long query(long long l, long long r,
                vector& v)
{
    // Find the lowerbound of l in v
    auto X = lower_bound(v.begin(), v.end(), l);
  
    // Find the upperbound of l in v
    auto Y = upper_bound(v.begin(), v.end(), r);
  
    // Return the difference
    // in their positions
    return (Y - X);
}
void PerformQuery(vector > arr,
                  int N)
{
  
    // Stores all the numbers in the range
    // [1, 1e18] having three set bits
    vector V;
  
    // Function call to perform the
    // precomputation
    precompute(V);
  
    // Iterate through each query
    for (auto it : arr) {
        long long L = it.first;
        long long R = it.second;
  
        // Print the answer
        cout << query(L, R, V) << "\n";
    }
}
  
// Driver Code
int main()
{
  
    // Input
    vector > arr
        = { { 11, 19 }, { 14, 19 } };
    int N = arr.size();
  
    // Function call
    PerformQuery(arr, N);
  
    return 0;
}


输出
4
2

时间复杂度: O(N*log(63 3 )+ 63 3 )
辅助空间: O(63 3 )