Queries for counts of multiples in an array

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}

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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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[0]);
  
    // 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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[0];
        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 */

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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 = [0]*(MAX + 1)
  
# Initializing "cnt" array with zeros
    cnt = [0]*(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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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[0];
        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

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?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[0];
    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
?>

chevron_right



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 contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeksorg. See your article appearing on the GeeksforGeeks main page and help other Geeks

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up