Queries for counts of multiples in an array

• Difficulty Level : Medium
• Last Updated : 29 Apr, 2021

Given an array of positive integers and many queries for divisibility. In every query, we are given an integer k ( > 0), we need to count all elements in the array which are perfectly divisible by ‘k’.
Example:

Input:
2 4 9 15 21 20
k = 2
k = 3
k = 5

Output:
3
3
2

Explanation:
Multiples of '2' in array are:- {2, 4, 20}
Multiples of '3' in array are:- {9, 15, 21}
Multiples of '5' in array are:- {15, 20}

Recommended: Please solve it on “PRACTICE” first, before moving on to the solution.

Simple Approach is to traverse over every value of ‘k’ in whole array and count total multiples by checking modulas of every element of array i.e., for every element of i (0 < i < n), check whether arr[i] % k == 0 or not. If it’s perfectly divisible of k, then increment count. Time complexity of this approach is O(n * k) which is not efficient for large number of queries of k.
Efficient approach is to use the concept of Sieve of Eratosthenes. Let’s define the maximum value in array[] is ‘Max’. Since multiples of all numbers in array[] will always be less than Max, therefore we will iterate up-to ‘Max’ only.
Now for every value(say ‘q’) iterate q, 2q, 3q, … t.k(tk <= MAX) because all these numbers are multiples of ‘q‘ .Meanwhile store the count of all these number for every value of q(1, 2, … MAX) in ans[] array. After that we can answer every query in O(1) time.

C++

// C++ program to calculate all multiples
// of integer 'k' in array[]
#include <bits/stdc++.h>
using namespace std;

// ans is global pointer so that both countSieve()
// and countMultiples() can access it.
int* ans = NULL;

// Function to pre-calculate all multiples of
// array elements
void countSieve(int arr[], int n)
{
int MAX = *max_element(arr, arr + n);

int cnt[MAX + 1];

// ans is global pointer so that query function
// can access it.
ans = new int[MAX + 1];

// Initialize both arrays as 0.
memset(cnt, 0, sizeof(cnt));
memset(ans, 0, (MAX + 1) * sizeof(int));

// Store the arr[] elements as index
// in cnt[] array
for (int i = 0; i < n; ++i)
++cnt[arr[i]];

// Iterate over all multiples as 'i'
// and keep the count of array[] ( In
// cnt[] array) elements in ans[] array
for (int i = 1; i <= MAX; ++i)
for (int j = i; j <= MAX; j += i)
ans[i] += cnt[j];
return;
}

int countMultiples(int k)
{
// return pre-calculated result
return ans[k];
}

// Driver code
int main()
{
int arr[] = { 2, 4, 9, 15, 21, 20 };
int n = sizeof(arr) / sizeof(arr);

// pre-calculate all multiples
countSieve(arr, n);

int k = 2;
cout << countMultiples(k) << "\n";

k = 3;
cout << countMultiples(k) << "\n";

k = 5;
cout << countMultiples(k) << "\n";
return 0;
}

Java

// Java program to calculate all multiples
// of integer 'k' in array[]
class CountMultiples {
// ans is global array so that both
// countSieve() and countMultiples()
// can access it.
static int ans[];

// Function to pre-calculate all
// multiples of array elements
static void countSieve(int arr[], int n)
{
int MAX = arr;
for (int i = 1; i < n; i++)
MAX = Math.max(arr[i], MAX);

int cnt[] = new int[MAX + 1];

// ans is global array so that
// query function can access it.
ans = new int[MAX + 1];

// Store the arr[] elements as
// index in cnt[] array
for (int i = 0; i < n; ++i)
++cnt[arr[i]];

// Iterate over all multiples as 'i'
// and keep the count of array[]
// (In cnt[] array) elements in ans[]
// array
for (int i = 1; i <= MAX; ++i)
for (int j = i; j <= MAX; j += i)
ans[i] += cnt[j];
return;
}

static int countMultiples(int k)
{
// return pre-calculated result
return ans[k];
}

// Driver code
public static void main(String args[])
{
int arr[] = { 2, 4, 9, 15, 21, 20 };
int n = 6;

// pre-calculate all multiples
countSieve(arr, n);

int k = 2;
System.out.println(countMultiples(k));

k = 3;
System.out.println(countMultiples(k));

k = 5;
System.out.println(countMultiples(k));
}
}

/*This code is contributed by Danish Kaleem */

Python3

# Python3 program to calculate all multiples
# of integer 'k' in array[]

# ans is global array so that both countSieve()
# and countMultiples() can access it.
ans = []

# Function to pre-calculate all multiples
# of array elements
# Here, the arguments are as follows
# a: given array
# n: length of given array
def countSieve(arr, n):

MAX=max(arr)

# Accessing the global array in the function
global ans

# Initializing "ans" array with zeros
ans = *(MAX + 1)

# Initializing "cnt" array with zeros
cnt = *(MAX + 1)

#Store the arr[] elements as index in cnt[] array
for i in range(n):
cnt[arr[i]] += 1

# Iterate over all multiples as 'i'
# and keep the count of array[] ( In
# cnt[] array) elements in ans[] array
for i in range(1, MAX+1):
for j in range(i, MAX+1, i):
ans[i] += cnt[j]

def countMultiples(k):
# Return pre-calculated result
return(ans[k])

# Driver code
if __name__ == "__main__":
arr = [2, 4, 9 ,15, 21, 20]
n=len(arr)
# Pre-calculate all multiples
countSieve(arr, n)
k=2
print(countMultiples(2))
k=3
print(countMultiples(3))
k=5
print(countMultiples(5))

# This code is contributed by Pratik Somwanshi

C#

// C# program to calculate all multiples
// of integer 'k' in array[]
using System;

class GFG {

// ans is global array so that both
// countSieve() and countMultiples()
// can access it.
static int[] ans;

// Function to pre-calculate all
// multiples of array elements
static void countSieve(int[] arr, int n)
{

int MAX = arr;
for (int i = 1; i < n; i++)
MAX = Math.Max(arr[i], MAX);

int[] cnt = new int[MAX + 1];

// ans is global array so that
// query function can access it.
ans = new int[MAX + 1];

// Store the arr[] elements as
// index in cnt[] array
for (int i = 0; i < n; ++i)
++cnt[arr[i]];

// Iterate over all multiples as
// 'i' and keep the count of
// array[] (In cnt[] array)
// elements in ans[] array
for (int i = 1; i <= MAX; ++i)
for (int j = i; j <= MAX; j += i)
ans[i] += cnt[j];

return;
}

static int countMultiples(int k)
{

// return pre-calculated result
return ans[k];
}

// Driver code
public static void Main()
{
int[] arr = { 2, 4, 9, 15, 21, 20 };
int n = 6;

// pre-calculate all multiples
countSieve(arr, n);

int k = 2;
Console.WriteLine(countMultiples(k));

k = 3;
Console.WriteLine(countMultiples(k));

k = 5;
Console.WriteLine(countMultiples(k));
}
}

// This code is contributed by nitin mittal

PHP

<?php
// PHP program to calculate
// all multiples of integer
// 'k' in array[]

// ans is global array so
// that both countSieve()
// and countMultiples()
// can access it.
\$ans;

// Function to pre-calculate all
// multiples of array elements
function countSieve(\$arr, \$n)
{
global \$ans;
\$MAX = \$arr;
for (\$i = 1; \$i < \$n; \$i++)
\$MAX = max(\$arr[\$i], \$MAX);

\$cnt = array_fill(0, \$MAX + 1, 0);

// ans is global array so that
// query function can access it.
\$ans = array_fill(0, \$MAX + 1, 0);

// Store the arr[] elements
// as index in cnt[] array
for (\$i = 0; \$i < \$n; ++\$i)
++\$cnt[\$arr[\$i]];

// Iterate over all multiples as 'i'
// and keep the count of array[]
// (In cnt[] array) elements in ans[]
// array
for (\$i = 1; \$i <= \$MAX; ++\$i)
for (\$j = \$i; \$j <= \$MAX; \$j += \$i)
\$ans[\$i] += \$cnt[\$j];
return;
}

function countMultiples(\$k)
{
global \$ans;

// return pre-calculated result
return \$ans[\$k];
}

// Driver code
\$arr = array( 2, 4, 9, 15, 21, 20);
\$n = 6;

// pre-calculate
// all multiples
countSieve(\$arr, \$n);

\$k = 2;
echo countMultiples(\$k) . "\n";

\$k = 3;
echo countMultiples(\$k) . "\n";

\$k = 5;
echo countMultiples(\$k) . "\n";

// This code is contributed by mits
?>

Javascript

<script>
// Javascript program to calculate all multiples
// of integer 'k' in array[]

// ans is global array so that both
// countSieve() and countMultiples()
// can access it.
let ans = [];

// Function to pre-calculate all
// multiples of array elements
function countSieve(arr, n)
{
let MAX = arr;
for (let i = 1; i < n; i++)
MAX = Math.max(arr[i], MAX);

let cnt = Array.from({length: MAX + 1}, (_, i) => 0);

// ans is global array so that
// query function can access it.
ans = Array.from({length: MAX + 1}, (_, i) => 0);

// Store the arr[] elements as
// index in cnt[] array
for (let i = 0; i < n; ++i)
++cnt[arr[i]];

// Iterate over all multiples as 'i'
// and keep the count of array[]
// (In cnt[] array) elements in ans[]
// array
for (let i = 1; i <= MAX; ++i)
for (let j = i; j <= MAX; j += i)
ans[i] += cnt[j];
return;
}

function countMultiples(k)
{
// return pre-calculated result
return ans[k];
}

// driver function

let arr = [ 2, 4, 9, 15, 21, 20 ];
let n = 6;

// pre-calculate all multiples
countSieve(arr, n);

let k = 2;
document.write(countMultiples(k) + "<br/>");

k = 3;
document.write(countMultiples(k) + "<br/>");

k = 5;
document.write(countMultiples(k) + "<br/>");

</script>

Output:

3
3
2

Time complexity: O(M*log(M)) where M is the maximum value in array elements.
Auxiliary space: O(MAX)
This article is contributed by Shubham Bansal. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to contribute@geeksforgeeksorg. See your article appearing on the GeeksforGeeks main page and help other Geeks

My Personal Notes arrow_drop_up