Open In App

Count of Array elements in given range with remainder X when divided by K for Q queries

Last Updated : 28 Aug, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of size N, an integer K and Q queries, each of form {x, l, r}. For each query, the task is to find the count of all elements in index range [l, r] which have remainder x when divided by K.

Examples:

Input: arr[] = {15, 28, 72, 43, 20, 0, 97}, K = 5, queries[] = {{3, 0, 3}, {0, 0, 6}, {6, 2, 4}}
Output: 2, 3, 0
Explanation: For the first query, there are 2 elements in the range [0, 3] whose remainder is 3 (28, 43). 
Similarly 3 elements in range [0, 6] whose remainder is 0 (15, 20, 0). 
In the third query, elements whose remainder are 6 should be found.
But for the given K = 5 possible remainders are only [0, 4]. So for any x >= K, answer will be 0.

Input: arr[] = {2, 4, 6, 7, 5}, K = 3, queries[] = {{2, 1, 4}}
Output: 1

 

Method 1: A simple approach is, for each query, iterate through l to r and count all elements whose remainder is x

Algorithm:

  1. For each query in the vector, extract the values of x, l and r from the query.
  2. Call the function ‘countRemainder‘ with the given parameters.
  3. Print the count returned by the function.
  4. In the function ‘countRemainder‘, initialize count as 0.
  5. For each index i in range l to r:
    •  Check if the remainder of arr[i] when divided by K is equal to x.
    •  If true, increment count.
    •  Return the count.

Below is the implementation of the approach:

C++




// C++ code for the approach
 
#include <iostream>
#include <vector>
using namespace std;
 
// Function to count elements in range [l, r] with remainder
// x when divided by K
int countRemainder(int arr[], int n, int K, int x, int l,
                   int r) {
    int count = 0;
    for (int i = l; i <= r; i++) {
        // Check if remainder is x
        // when divided by K
        if (arr[i] % K == x) {
            // Increment count if condition is true
            count++;
        }
    }
 
    // Return the count
    return count;
}
 
// Driver's code
int main() {
      // Input array, K and Queries
    int arr[] = { 15, 28, 72, 43, 20, 0, 97 };
 
    int K = 5;
    int N = sizeof(arr) / sizeof(arr[0]);
    vector<vector<int> > queries{ { 3, 0, 3 },
                                  { 0, 0, 6 },
                                  { 6, 2, 4 } };
       
       
      for( int i = 0; i < queries.size(); i++) {
        int x = queries[i][0];
          int l = queries[i][1];
          int r = queries[i][2]; 
           
          // Function call
        int count = countRemainder(arr, N, K, x, l, r);
        cout << count << " ";
    }
 
    return 0;
}


Java




// Java code for the approach
import java.util.*;
 
public class Main
{
   
    // Function to count elements in range [l, r] with remainder
    // x when divided by K
    static int countRemainder(int[] arr, int n, int K, int x, int l, int r) {
        int count = 0;
        for (int i = l; i <= r; i++)
        {
           
            // Check if remainder is x when divided by K
            if (arr[i] % K == x)
            {
               
                // Increment count if condition is true
                count++;
            }
        }
        // Return the count
        return count;
    }
     
    // Driver's code
    public static void main(String[] args)
    {
       
        // Input array, K and Queries
        int[] arr = { 15, 28, 72, 43, 20, 0, 97 };
        int K = 5;
        int N = arr.length;
        List<List<Integer>> queries = new ArrayList<>();
        queries.add(Arrays.asList(3, 0, 3));
        queries.add(Arrays.asList(0, 0, 6));
        queries.add(Arrays.asList(6, 2, 4));
         
        for (List<Integer> query : queries) {
            int x = query.get(0);
            int l = query.get(1);
            int r = query.get(2);
             
            // Function call
            int count = countRemainder(arr, N, K, x, l, r);
            System.out.print(count + " ");
        }
    }
}
 
// This code is contributed by Vaibhav


Python3




# Function to count elements in range [l, r] with remainder
# x when divided by K
def countRemainder(arr, n, K, x, l, r):
    count = 0
    for i in range(l, r+1):
        # Check if remainder is x
        # when divided by K
        if arr[i] % K == x:
            # Increment count if condition is true
            count += 1
 
    # Return the count
    return count
 
   
# test case
arr = [15, 28, 72, 43, 20, 0, 97]
K = 5
N = len(arr)
queries = [[3, 0, 3], [0, 0, 6], [6, 2, 4]]
for query in queries:
    x, l, r = query
    count = countRemainder(arr, N, K, x, l, r)
    print(count, end=" ")


C#




//C# code for the above approach
using System;
using System.Collections.Generic;
 
class GFG
{
    // Function to count elements in range [l, r] with remainder
    // x when divided by K
    static int CountRemainder(int[] arr, int K, int x, int l, int r)
    {
        int count = 0;
        for (int i = l; i <= r; i++)
        {
            // Check if remainder is x
            // when divided by K
            if (arr[i] % K == x)
            {
                // Increment count if condition is true
                count++;
            }
        }
 
        // Return the count
        return count;
    }
 
    static void Main(string[] args)
    {
        // Input array, K, and Queries
        int[] arr = { 15, 28, 72, 43, 20, 0, 97 };
        int K = 5;
        int N = arr.Length;
        List<List<int>> queries = new List<List<int>>
        {
            new List<int> { 3, 0, 3 },
            new List<int> { 0, 0, 6 },
            new List<int> { 6, 2, 4 }
        };
 
        foreach (var query in queries)
        {
            int x = query[0];
            int l = query[1];
            int r = query[2];
 
            // Function call
            int count = CountRemainder(arr, K, x, l, r);
            Console.Write(count + " ");
        }
    }
}


Javascript




// Function to count elements in range [l, r] with remainder
// x when divided by K
function countRemainder(arr, n, K, x, l, r) {
  let count = 0;
  for (let i = l; i <= r; i++) {
       
    // Check if remainder is x
    // when divided by K
    if (arr[i] % K === x) {
     
    // Increment count if condition is true
      count++;
    }
  }
   
  // Returning result
  return count;
}
 
 
// Test case
const arr = [15, 28, 72, 43, 20, 0, 97];
const K = 5;
const N = arr.length;
const queries = [[3, 0, 3], [0, 0, 6], [6, 2, 4]];
 
for (let i = 0; i < queries.length; i++) {
  const x = queries[i][0];
  const l = queries[i][1];
  const r = queries[i][2];
  const count = countRemainder(arr, N, K, x, l, r);
  console.log(count + " ");
}


Output

2 3 0 



Time Complexity: O(N * Q)
Auxiliary Space: O(1)

Method 2: This problem can also be solved with help of precalculation based on the following idea:

Precalculate what will be the remainder, when arr[i] is divided by K and store them in a matrix (say mat[]) where mat[i][j] represents the remainder of arr[j] is i when divided by K.
Now prefix sum of ith row of the matrix gives the count of elements which will have remainder i when divided by K. Therefore, after prefix sum mat[i][j] will represent total count of elements till jth index having remainder i when divided by K.
So for a query {x, l, r} the answer will be (mat[x][r] – mat[x][l] [+1 if arr[l]%K is x])

Follow the illustration below for a better understanding of the construction of the matrix.

Illustration:

Consider arr[] = {15, 28, 72, 43, 20, 0, 97}, K = 5

Make a 2D matrix named precompute, of size (K*N), and initialize it with 0. 
For the ith element, mark  precompute[arr[i]%K][i] = 1, do this for all i which states that the ith element has remainder arr[i]%K.

For the given example our precompute matrix will look like the following where row: remainder, column: index num.

  0 1 2 3 4 5 6
0 1 0 0 0 1 1 0
1 0 0 0 0 0 0 0
2 0 0 1 0 0 0 1
3 0 1 0 1 0 0 0
4 0 0 0 0 0 0 0

Then for each row calculate prefix sum. Now matrix will look like this:

  0 1 2 3 4 5 6
0 1 1 1 1 2 3 3
1 0 0 0 0 0 0 0
2 0 0 1 1 1 1 2
3 0 1 1 2 2 2 2
4 0 0 0 0 0 0 0

Here precompute[0][6] denotes that till 6th index there are a total of 3 elements which will have remainder 3 when divided by 5.

Follow the steps mentioned below to implement the idea:

  • Create the 2D array (say precompute).
  • Construct the array as mentioned above.
  • Traverse the queries:
    • For each query calculate the number of elements as per the formula shown above and store that in the answer array.
  • Return the array having the answers.

Note: This method is more efficient only when the number of queries is greater than K.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
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<int> findCount(int arr[], int K, int N,
                      vector<vector<int> >& queries)
{
    vector<int> res;
 
    // Initialise matrix with 0
    memset(precompute, 0, sizeof precompute);
 
    // To calculate count of remainders
    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<vector<int> > queries{ { 3, 0, 3 },
                                  { 0, 0, 6 },
                                  { 6, 2, 4 } };
 
    vector<int> ans
        = findCount(arr, K, N, queries);
    for (int x : ans)
        cout << x << " ";
    return 0;
}


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<Integer>
    findCount(int[] arr, int K, int N, int[][] queries)
  {
    ArrayList<Integer> res = new ArrayList<Integer>();
 
    // Initialise 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 remainders
    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<Integer> ans
      = findCount(arr, K, N, queries);
    for (int i = 0; i < ans.size(); i++)
      System.out.print(ans.get(i) + " ");
  }
}
 
// This code is contributed by phasing17


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 = []
 
    # Initialise matrix with 0
 
    # To calculate count of remainders
    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


C#




// C# code for the above discussed approach
using System;
using System.Collections;
 
public 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)
  {
    var res = new ArrayList();
 
    // Initialise 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 remainders
    precomputation(arr, N, K);
 
    for (int i = 0; i < queries.GetLength(0); 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.Count; i++)
      Console.Write(ans[i] + " ");
  }
}
 
// This code is contributed by phasing17


Javascript




<script>
        // JavaScript code for the above approach
        let MXN = 2e5;
        let precompute = new Array(100);
 
        for (let i = 0; i < precompute.length; i++) {
            precompute[i] = new Array(MXN).fill(0);
        }
 
        // To precompute count prefix sum of all
        // possible remainders
        function precomputation(arr, n, k)
        {
         
            // Mark cell whose remainder is arr[i]%k
            for (let i = 0; i < n; i++)
                precompute[arr[i] % k][i] = 1;
 
            // Take prefix sum for all rows
            for (let i = 0; i < k; i++) {
                for (let j = 1; j < n; j++) {
                    precompute[i][j]
                        += precompute[i][j - 1];
                }
            }
        }
 
        // Function to find the
        // count of numbers for the queries
        function findCount(arr, K, N, queries) {
            let res = [];
 
            // To calculate count of remainders
            precomputation(arr, N, K);
            for (let i = 0; i < queries.length; i++) {
                let x = queries[i][0];
                let l = queries[i][1];
                let r = queries[i][2];
                if (x >= K) {
                    res.push(0);
                    continue;
                }
                let count = precompute[x][r]
                    - precompute[x][l]
                    + (arr[l] % K == x);
                res.push(count);
            }
            return res;
        }
 
        // Driver code
        let arr = [15, 28, 72, 43, 20, 0, 97];
 
        let K = 5;
        let N = arr.length;
        let queries = [[3, 0, 3],
        [0, 0, 6],
        [6, 2, 4]];
 
        let ans
            = findCount(arr, K, N, queries);
        for (let x of ans)
            document.write(x + " ")
 
    // This code is contributed by Potta Lokesh
    </script>


Output

2 3 0 



Time Complexity: O(Q + K*N)
Auxiliary Space: O(K*N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads