Count of Array elements in given range with remainder X when divided by K for Q queries
Last Updated :
28 Aug, 2023
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:
- For each query in the vector, extract the values of x, l and r from the query.
- Call the function ‘countRemainder‘ with the given parameters.
- Print the count returned by the function.
- In the function ‘countRemainder‘, initialize count as 0.
- 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++
#include <iostream>
#include <vector>
using namespace std;
int countRemainder( int arr[], int n, int K, int x, int l,
int r) {
int count = 0;
for ( int i = l; i <= r; i++) {
if (arr[i] % K == x) {
count++;
}
}
return count;
}
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 } };
for ( int i = 0; i < queries.size(); i++) {
int x = queries[i][0];
int l = queries[i][1];
int r = queries[i][2];
int count = countRemainder(arr, N, K, x, l, r);
cout << count << " " ;
}
return 0;
}
|
Java
import java.util.*;
public class Main
{
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++)
{
if (arr[i] % K == x)
{
count++;
}
}
return count;
}
public static void main(String[] args)
{
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 );
int count = countRemainder(arr, N, K, x, l, r);
System.out.print(count + " " );
}
}
}
|
Python3
def countRemainder(arr, n, K, x, l, r):
count = 0
for i in range (l, r + 1 ):
if arr[i] % K = = x:
count + = 1
return count
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#
using System;
using System.Collections.Generic;
class GFG
{
static int CountRemainder( int [] arr, int K, int x, int l, int r)
{
int count = 0;
for ( int i = l; i <= r; i++)
{
if (arr[i] % K == x)
{
count++;
}
}
return count;
}
static void Main( string [] args)
{
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];
int count = CountRemainder(arr, K, x, l, r);
Console.Write(count + " " );
}
}
}
|
Javascript
function countRemainder(arr, n, K, x, l, r) {
let count = 0;
for (let i = l; i <= r; i++) {
if (arr[i] % K === x) {
count++;
}
}
return count;
}
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 + " " );
}
|
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++
#include <bits/stdc++.h>
using namespace std;
const int MXN = 2e5;
int precompute[100][MXN];
void precomputation( int arr[], int n, int k)
{
for ( int i = 0; i < n; i++)
precompute[arr[i] % k][i] = 1;
for ( int i = 0; i < k; i++) {
for ( int j = 1; j < n; j++) {
precompute[i][j]
+= precompute[i][j - 1];
}
}
}
vector< int > findCount( int arr[], int K, int N,
vector<vector< int > >& queries)
{
vector< int > res;
memset (precompute, 0, sizeof precompute);
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;
}
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
import java.io.*;
import java.util.ArrayList;
class GFG {
static int MXN = 200000 ;
static int [][] precompute = new int [ 100 ][MXN];
static void precomputation( int [] arr, int n, int k)
{
for ( int i = 0 ; i < n; i++)
precompute[arr[i] % k][i] = 1 ;
for ( int i = 0 ; i < k; i++) {
for ( int j = 1 ; j < n; j++) {
precompute[i][j] += precompute[i][j - 1 ];
}
}
}
static ArrayList<Integer>
findCount( int [] arr, int K, int N, int [][] queries)
{
ArrayList<Integer> res = new ArrayList<Integer>();
for ( int i = 0 ; i < 100 ; i++) {
for ( int j = 0 ; j < MXN; j++)
precompute[i][j] = 0 ;
}
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;
}
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) + " " );
}
}
|
Python3
MXN = int ( 2e5 )
precompute = [[ 0 for _ in range (MXN)] for _ in range ( 100 )]
def precomputation(arr, n, k):
global precompute
for i in range ( 0 , n):
precompute[arr[i] % k][i] = 1
for i in range ( 0 , k):
for j in range ( 1 , n):
precompute[i][j] + = precompute[i][j - 1 ]
def findCount(arr, K, N, queries):
global precompute
res = []
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
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 = " " )
|
C#
using System;
using System.Collections;
public class GFG {
static int MXN = 200000;
static int [, ] precompute = new int [100, MXN];
static void precomputation( int [] arr, int n, int k)
{
for ( int i = 0; i < n; i++)
precompute[arr[i] % k, i] = 1;
for ( int i = 0; i < k; i++) {
for ( int j = 1; j < n; j++) {
precompute[i, j] += precompute[i, j - 1];
}
}
}
static ArrayList findCount( int [] arr, int K, int N,
int [, ] queries)
{
var res = new ArrayList();
for ( int i = 0; i < 100; i++) {
for ( int j = 0; j < MXN; j++)
precompute[i, j] = 0;
}
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;
}
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] + " " );
}
}
|
Javascript
<script>
let MXN = 2e5;
let precompute = new Array(100);
for (let i = 0; i < precompute.length; i++) {
precompute[i] = new Array(MXN).fill(0);
}
function precomputation(arr, n, k)
{
for (let i = 0; i < n; i++)
precompute[arr[i] % k][i] = 1;
for (let i = 0; i < k; i++) {
for (let j = 1; j < n; j++) {
precompute[i][j]
+= precompute[i][j - 1];
}
}
}
function findCount(arr, K, N, queries) {
let res = [];
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;
}
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 + " " )
</script>
|
Time Complexity: O(Q + K*N)
Auxiliary Space: O(K*N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...