📌  相关文章
📜  给定范围内的数组元素计数,当 Q 查询除以 K 时余数为 X

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

给定范围内的数组元素计数,当 Q 查询除以 K 时余数为 X

给定一个大小为N的数组arr[] ,一个整数KQ查询,每个查询的形式为{x, l, r} 。对于每个查询,任务是查找索引范围[l, r]中除以K时余数为x的所有元素的计数。

例子:

方法 1:一种简单的方法是,对于每个查询,遍历l 到 r并计算余数为x的所有元素。

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

方法二:这个问题也可以通过基于以下思路的预计算来解决:

请按照下图更好地理解矩阵的构造。

插图:

按照下面提到的步骤来实现这个想法:

  • 创建二维数组(比如precompute )。
  • 如上所述构造数组。
  • 遍历查询:
    • 对于每个查询,根据上面显示的公式计算元素的数量并将其存储在答案数组中。
  • 返回有答案的数组。

注意:此方法仅在查询数大于K时更有效。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
const int MXN = 2e5;
int precompute[100][MXN];
 
// To precompute count prefix sum of all
// possible remainders
void precomputation(int arr[], int n, int k)
{
    // Mark cell whose remainder is arr[i]%k
    for (int i = 0; i < n; i++)
        precompute[arr[i] % k][i] = 1;
 
    // Take prefix sum for all rows
    for (int i = 0; i < k; i++) {
        for (int j = 1; j < n; j++) {
            precompute[i][j]
                += precompute[i][j - 1];
        }
    }
}
 
// Function to find the
// count of numbers for the queries
vector findCount(int arr[], int K, int N,
                      vector >& queries)
{
    vector res;
 
    // Intialise matrix with 0
    memset(precompute, 0, sizeof precompute);
 
    // To calculate count of reaminders
    precomputation(arr, N, K);
    for (int i = 0; i < queries.size(); i++) {
        int x = queries[i][0];
        int l = queries[i][1];
        int r = queries[i][2];
        if (x >= K) {
            res.push_back(0);
            continue;
        }
        int count = precompute[x][r]
                    - precompute[x][l]
                    + (arr[l] % K == x);
        res.push_back(count);
    }
    return res;
}
 
// Driver code
int main()
{
    int arr[] = { 15, 28, 72, 43, 20, 0, 97 };
 
    int K = 5;
    int N = sizeof(arr) / sizeof(arr[0]);
    vector > queries{ { 3, 0, 3 },
                                  { 0, 0, 6 },
                                  { 6, 2, 4 } };
 
    vector ans
        = findCount(arr, K, N, queries);
    for (int x : ans)
        cout << x << " ";
    return 0;
}


Python3
# python3 program for the above approach
MXN = int(2e5)
precompute = [[0 for _ in range(MXN)] for _ in range(100)]
 
# To precompute count prefix sum of all
# possible remainders
def precomputation(arr, n, k):
    global precompute
    # Mark cell whose remainder is arr[i]%k
    for i in range(0, n):
        precompute[arr[i] % k][i] = 1
 
        # Take prefix sum for all rows
    for i in range(0, k):
        for j in range(1, n):
            precompute[i][j] += precompute[i][j - 1]
 
# Function to find the
# count of numbers for the queries
def findCount(arr, K, N, queries):
    global precompute
    res = []
 
    # Intialise matrix with 0
 
    # To calculate count of reaminders
    precomputation(arr, N, K)
    for i in range(0, len(queries)):
        x = queries[i][0]
        l = queries[i][1]
        r = queries[i][2]
        if (x >= K):
            res.append(0)
            continue
 
        count = precompute[x][r] - precompute[x][l] + (arr[l] % K == x)
        res.append(count)
 
    return res
 
# Driver code
if __name__ == "__main__":
 
    arr = [15, 28, 72, 43, 20, 0, 97]
 
    K = 5
    N = len(arr)
    queries = [[3, 0, 3],
               [0, 0, 6],
               [6, 2, 4]]
 
    ans = findCount(arr, K, N, queries)
    for x in ans:
        print(x, end=" ")
 
    # This code is contributed by rakeshsahni


Javascript


Java
// Java program for the above approach
import java.io.*;
import java.util.ArrayList;
 
class GFG {
 
    static int MXN = 200000;
    static int[][] precompute = new int[100][MXN];
 
    // To precompute count prefix sum of all
    // possible remainders
    static void precomputation(int[] arr, int n, int k)
    {
        // Mark cell whose remainder is arr[i]%k
        for (int i = 0; i < n; i++)
            precompute[arr[i] % k][i] = 1;
 
        // Take prefix sum for all rows
        for (int i = 0; i < k; i++) {
            for (int j = 1; j < n; j++) {
                precompute[i][j] += precompute[i][j - 1];
            }
        }
    }
 
    // Function to find the
    // count of numbers for the queries
    static ArrayList
    findCount(int[] arr, int K, int N, int[][] queries)
    {
        ArrayList res = new ArrayList();
 
        // Intialise matrix with 0
        for (int i = 0; i < 100; i++) {
            for (int j = 0; j < MXN; j++)
                precompute[i][j] = 0;
        }
 
        // To calculate count of reaminders
        precomputation(arr, N, K);
 
        for (int i = 0; i < queries.length; i++) {
            int x = queries[i][0];
            int l = queries[i][1];
            int r = queries[i][2];
            if (x >= K) {
                res.add(0);
                continue;
            }
            int count = precompute[x][r] - precompute[x][l]
                        + ((arr[l] % K == x) ? 1 : 0);
            res.add(count);
        }
        return res;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 15, 28, 72, 43, 20, 0, 97 };
 
        int K = 5;
        int N = arr.length;
        int[][] queries
            = { { 3, 0, 3 }, { 0, 0, 6 }, { 6, 2, 4 } };
 
        ArrayList ans
            = findCount(arr, K, N, queries);
        for (int i = 0; i < ans.size(); i++)
            System.out.print(ans.get(i) + " ");
    }
}
 
//thise code was contributed by phasing17


输出
2 3 0 

时间复杂度: O(Q + K*N)
辅助空间: O(K*N)