Open In App

Prime Factorization for multiple queries using Sieve

Last Updated : 12 Nov, 2025
Suggest changes
Share
125 Likes
Like
Report

Given an array arr[] of integers, find the prime factorization of each number efficiently using Sieve that stores the smallest prime factor (SPF).

Examples:

Input: arr[] = [15, 17, 21]
Output: [[3, 5], [17], [7, 3]]
Explanation: prime factors of:
15 -> 3, 5 as 3* 5 = 15
17, as 17 itself is a prime number so there is no other prime factors of 17
21 ->3, 7 as 3* 7 = 21

Prerequisites : Sieve of Eratosthenes, Least prime factor of numbers till n.

Approach

To solve this problem, we first need the Smallest Prime Factor (SPF) of each number, as SPF allows us to repeatedly divide a number by its smallest prime factor until it becomes 1, through which we can easily get its prime factors.
To calculate to smallest prime factor for every number we will use the modified approach of sieve of eratosthenes.
The key idea is to precompute the smallest prime that divides each number. Once this SPF array is prepared, the a factorization function will calculate the prime factors of the integers of the array.

Step-by-step approach of above idea:

  • Defines a constant MAXN equal to 100001, representing the upper limit for precomputation.
  • Declare a vector spf of size MAXN + 1, initialized with 1, to store the smallest prime factor (SPF) of every number up to MAXN.
  • Defines a function sieve() to precompute the smallest prime factor for all numbers up to MAXN using a modified Sieve of Eratosthenes, in which the smallest prime factor for the all the number is initially set to 1.
  • Defines a function getFactorization() that returns the prime factorization of a number of array using the precomputed spf array.
  • Inside getFactorization(), the sieve() function is called to precompute the smallest prime factor of every number up to MAXN for every number of array the smallest prime factor of that number is repeatedly added to a result vector, and the number is divided by that factor until it becomes 1.

The implementation for the above method is given below : 

C++
#include <iostream>
#include <vector>
using namespace std;

// MAXN is the maximum number up to which we precompute smallest prime factors
#define MAXN 100001
vector<int> spf(MAXN + 1, 1);

// Calculating SPF (Smallest Prime Factor) for every number till MAXN.
void sieve()
{
    // stores smallest prime factor for every number
    spf[0] = 0;
    for (int i = 2; i <= MAXN; i++) {
        if (spf[i] == 1) { 
            
            // if the number is prime ,mark
            // all its multiples who havent
            // gotten their spf yet
            for (int j = i; j <= MAXN; j += i) {
                if (spf[j]== 1) 
                
                    // if its smallest prime factor is
                    // 1 means its spf hasnt been
                    // found yet so change it to i
                    spf[j] = i;
            }
        }
    }
}

vector<vector<int>> getFactorization(vector<int> arr)
{
    // precalculating Smallest Prime Factor
    sieve();
    vector<vector<int>> ret;
    for(int i = 0; i < arr.size(); i++){
        vector<int> Pfactors;
        int x = arr[i];
        while (x != 1) {
            Pfactors.push_back(spf[x]);
            x = x / spf[x];
        }
        ret.push_back(Pfactors);
    }
    return ret;
}

int main()
{
    vector<int> arr = {15, 17, 21};

    // calling getFactorization function
    vector<vector<int>> pfactors = getFactorization(arr);
    
    // printing prime factors of querry
    for (int i = 0; i < pfactors.size(); i++){
        for(int j = 0; j < pfactors[i].size(); j++)
        cout << pfactors[i][j] << " ";
        cout << endl;
    }
    cout << endl;
    return 0;
}
Java
import java.util.ArrayList;
import java.util.Arrays;

public class Main {

    // MAXN is the maximum number up to which we precompute smallest prime factors
    static final int MAXN = 100001;
    static int[] spf = new int[MAXN + 1];

    // Calculating SPF (Smallest Prime Factor) for every number till MAXN.
    static void sieve() {
        // stores smallest prime factor for every number
        spf[0] = 0;
        Arrays.fill(spf, 1); 
        for (int i = 2; i <= MAXN; i++) {
            if (spf[i] == 1) {

                // if the number is prime, mark
                // all its multiples who haven't
                // gotten their spf yet
                for (int j = i; j <= MAXN; j += i) {
                    if (spf[j] == 1)

                        // if its smallest prime factor is
                        // 1 means its spf hasn't been
                        // found yet so change it to i
                        spf[j] = i;
                }
            }
        }
    }

    static ArrayList<ArrayList<Integer>> getFactorization(int[] arr) {
        
        // precalculating Smallest Prime Factor
        sieve();
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();

        // iterate through all query numbers
        for (int j = 0; j < arr.length; j++) {
            ArrayList<Integer> factors = new ArrayList<>();
            int x = arr[j];

            // keep dividing by smallest prime factor till x becomes 1
            while (x != 1) {
                factors.add(spf[x]);
                x = x / spf[x];
            }

            // store factor list for this number
            result.add(factors);
        }
        return result;
    }

    public static void main(String[] args) {
        
        int[] arr = {15, 17, 21};

        // calling getFactorization function
        ArrayList<ArrayList<Integer>> allFactors = getFactorization(arr);

        // printing prime factors of each query number
        for (int i = 0; i < allFactors.size(); i++) {
            for (int j = 0; j < allFactors.get(i).size(); j++)
                System.out.print(allFactors.get(i).get(j) + " ");
            System.out.println(); 
        }
        System.out.println();
    }
}
Python
# MAXN is the maximum number up to which we precompute smallest prime factors
MAXN = 100001
spf = [1] * (MAXN + 1)  

# Calculating SPF (Smallest Prime Factor) for every number till MAXN.
def sieve():
    # stores smallest prime factor for every number
    spf[0] = 0
    for i in range(2, MAXN + 1):
        if spf[i] == 1:

            # if the number is prime, mark
            # all its multiples who haven't
            # gotten their spf yet
            for j in range(i, MAXN + 1, i):
                if spf[j] == 1:

                    # if its smallest prime factor is
                    # 1 means its spf hasn't been
                    # found yet so change it to i
                    spf[j] = i


def getFactorization(arr):
    # precalculating Smallest Prime Factor
    sieve()
    result = []

    # iterate over each number in queries
    for num in arr:
        factors = []
        x = num

        # repeatedly divide by smallest prime factor
        while x != 1:
            factors.append(spf[x])
            x //= spf[x]

        # store the factor list for this number
        result.append(factors)

    return result


if __name__ == "__main__":
    
    arr = [15, 17, 21]

    # calling getFactorization function
    all_factors = getFactorization(arr)

    # printing prime factors of each query number
    for factors in all_factors:
        for f in factors:
            print(f, end=" ")
        print()  
    print()
C#
using System;
using System.Collections.Generic;

class MainClass
{
    // MAXN is the maximum number up to which we precompute smallest prime factors
    static int MAXN = 100001;
    static int[] spf = new int[MAXN + 1];

    // Calculating SPF (Smallest Prime Factor) for every number till MAXN.
    static void sieve()
    {
        // stores smallest prime factor for every number
        spf[0] = 0;
        for (int i = 0; i <= MAXN; i++)
            spf[i] = 1; 

        for (int i = 2; i <= MAXN; i++)
        {
            if (spf[i] == 1)
            {
                // if the number is prime, mark
                // all its multiples who haven't
                // gotten their spf yet
                for (int j = i; j <= MAXN; j += i)
                {
                    if (spf[j] == 1)

                        // if its smallest prime factor is
                        // 1 means its spf hasn't been
                        // found yet so change it to i
                        spf[j] = i;
                }
            }
        }
    }

    static List<List<int>> getFactorization(int[] arr)
    {
        // precalculating Smallest Prime Factor
        sieve();
        List<List<int>> result = new List<List<int>>();

        // iterate over each query number
        foreach (int num in arr)
        {
            List<int> factors = new List<int>();
            int x = num;

            // keep dividing by smallest prime factor till x becomes 1
            while (x != 1)
            {
                factors.Add(spf[x]);
                x = x / spf[x];
            }

            // store the factor list for this number
            result.Add(factors);
        }

        return result;
    }

    public static void Main(string[] args)
    {
        int[] arr = {15, 17, 21};

        // calling getFactorization function
        List<List<int>> allFactors = getFactorization(arr);

        // printing prime factors of each query number
        foreach (List<int> factors in allFactors)
        {
            foreach (int factor in factors)
                Console.Write(factor + " ");
            Console.WriteLine(); 
        }
        Console.WriteLine();
    }
}
JavaScript
// MAXN is the maximum number up to which we precompute smallest prime factors
const MAXN = 100001;
let spf = new Array(MAXN + 1).fill(1); 

// Calculating SPF (Smallest Prime Factor) for every number till MAXN.
function sieve() {
    // stores smallest prime factor for every number
    spf[0] = 0;
    for (let i = 2; i <= MAXN; i++) {
        if (spf[i] === 1) {

            // if the number is prime, mark
            // all its multiples who haven't
            // gotten their spf yet
            for (let j = i; j <= MAXN; j += i) {
                if (spf[j] === 1)

                    // if its smallest prime factor is
                    // 1 means its spf hasn't been
                    // found yet so change it to i
                    spf[j] = i;
            }
        }
    }
}

function getFactorization(arr) {
    // precalculating Smallest Prime Factor
    sieve();
    let result = [];

    // iterate over each query number
    for (let num of arr) {
        let factors = [];
        let x = num;

        // repeatedly divide by smallest prime factor
        while (x !== 1) {
            factors.push(spf[x]);
            x = Math.floor(x / spf[x]);
        }

        // store factors for this number
        result.push(factors);
    }

    return result;
}

// driver code
let arr = [15, 17, 21];

// calling getFactorization function
let allFactors = getFactorization(arr);

// printing prime factors of each query number
for (let factors of allFactors) {
    for (let factor of factors)
        process.stdout.write(factor + " ");
    console.log(); 
}
console.log();
PHP
<?php
// MAXN is the maximum number up to which we precompute smallest prime factors
define("MAXN", 100001);

// Initialize SPF array where spf[i] = smallest prime factor of i
$spf = array_fill(0, MAXN + 1, 1); 

/**
 * Function to precompute the smallest prime factor (SPF)
 * for every number up to MAXN.
 */
function sieve() {
    global $spf;

    // stores smallest prime factor for every number
    $spf[0] = 0;

    for ($i = 2; $i <= MAXN; $i++) {

        // If spf[i] is still 1, it means it's a prime number
        if ($spf[$i] == 1) {

            // if the number is prime, mark
            // all its multiples who haven't
            // gotten their spf yet
            for ($j = $i; $j <= MAXN; $j += $i) {
                if ($spf[$j] == 1)

                    // if its smallest prime factor is
                    // 1 means its spf hasn't been
                    // found yet so change it to i
                    $spf[$j] = $i;
            }
        }
    }
}

function getFactorization($arr) {
    global $spf;

    // precalculating Smallest Prime Factor
    sieve();

    $result = array();

    // iterate through each number in queries
    foreach ($arr as $num) {
        $factors = array();
        $x = $num;

        // keep dividing by smallest prime factor till x becomes 1
        while ($x != 1) {
            $factors[] = $spf[$x];
            $x = (int)($x / $spf[$x]);
        }

        // store the factor list for this number
        $result[] = $factors;
    }

    return $result;
}

function main() {
    $arr = array(15, 17, 21);

    // calling getFactorization function
    $allFactors = getFactorization($arr);

    // printing prime factors of each query number
    foreach ($allFactors as $factors) {
        foreach ($factors as $f)
            echo $f . " ";
        echo "\n"; 
    }

    echo "\n";
}

main();
?>

Output: 

3 5
17
3 7

Time Complexity: O(log n), for each query.
The precomputation for smallest prime factor is done in O(n log log n) using sieve. Whereas in the calculation step we are dividing the number every time by the smallest prime number till it becomes 1. So, let's consider a worst case in which every time the SPF is 2 . Therefore will have log n division steps. Hence, We can say that our Time Complexity will be O(log n) in worst case.

Auxiliary Space: O(1)

Note : The above code works well for n up to the order of 10^7. Beyond this we will face memory issues.


Explore