📜  使用Sieve O(log n)进行质因子分解以进行多个查询

📅  最后修改于: 2021-04-29 08:23:09             🧑  作者: Mango

我们可以计算O(sqrt(n))中的数字“ n”的素因式分解,如此处所述。但是,当我们需要回答有关素因数分解的多个查询时,O(sqrt n)方法会超时。

在本文中,我们研究了一种使用O(n)空间和O(log n)时间复杂度并允许每次计算的方法来计算质因数分解的有效方法。

先决条件: Eratosthenes筛,直到n的数字的最小素因数。

为了计算每个数字的最小素因数,我们将使用eratosthenes的筛子。在原始的Sieve中,每当我们将数字标记为非质数时,我们都会为该数字存储相应的最小质数(请参阅本文以获得更好的理解)。

现在,在完成每个数字的最小素数的预计算之后,我们将数字n(要计算素数分解的数)除以其相应的最小素数,直到n变为1。

Pseudo Code for prime factorization assuming
SPFs are computed :

PrimeFactors[] // To store result

i = 0  // Index in PrimeFactors

while n != 1 :

    // SPF : smallest prime factor
    PrimeFactors[i] = SPF[n]    
    i++ 
    n = n / SPF[n]

上述方法的实现如下:

C++
// C++ program to find prime factorization of a
// number n in O(Log n) time with precomputation
// allowed.
#include "bits/stdc++.h"
using namespace std;
  
#define MAXN   100001
  
// stores smallest prime factor for every number
int spf[MAXN];
  
// Calculating SPF (Smallest Prime Factor) for every
// number till MAXN.
// Time Complexity : O(nloglogn)
void sieve()
{
    spf[1] = 1;
    for (int i=2; i getFactorization(int x)
{
    vector ret;
    while (x != 1)
    {
        ret.push_back(spf[x]);
        x = x / spf[x];
    }
    return ret;
}
  
// driver program for above function
int main(int argc, char const *argv[])
{
    // precalculating Smallest Prime Factor
    sieve();
    int x = 12246;
    cout << "prime factorization for " << x << " : ";
  
    // calling getFactorization function
    vector  p = getFactorization(x);
  
    for (int i=0; i


Java
// Java program to find prime factorization of a
// number n in O(Log n) time with precomputation
// allowed.
  
import java.util.Vector;
  
class Test
{
    static final int MAXN = 100001;
       
    // stores smallest prime factor for every number
    static int spf[] = new int[MAXN];
       
    // Calculating SPF (Smallest Prime Factor) for every
    // number till MAXN.
    // Time Complexity : O(nloglogn)
    static void sieve()
    {
        spf[1] = 1;
        for (int i=2; i getFactorization(int x)
    {
        Vector ret = new Vector<>();
        while (x != 1)
        {
            ret.add(spf[x]);
            x = x / spf[x];
        }
        return ret;
    }
       
    // Driver method
    public static void main(String args[])
    {
        // precalculating Smallest Prime Factor
        sieve();
        int x = 12246;
        System.out.print("prime factorization for " + x + " : ");
       
        // calling getFactorization function
        Vector  p = getFactorization(x);
       
        for (int i=0; i


Python3
# Python3 program to find prime factorization 
# of a number n in O(Log n) time with 
# precomputation allowed.
import math as mt
  
MAXN = 100001
  
# stores smallest prime factor for
# every number
spf = [0 for i in range(MAXN)]
  
# Calculating SPF (Smallest Prime Factor) 
# for every number till MAXN.
# Time Complexity : O(nloglogn)
def sieve():
    spf[1] = 1
    for i in range(2, MAXN):
          
        # marking smallest prime factor 
        # for every number to be itself.
        spf[i] = i
  
    # separately marking spf for 
    # every even number as 2
    for i in range(4, MAXN, 2):
        spf[i] = 2
  
    for i in range(3, mt.ceil(mt.sqrt(MAXN))):
          
        # checking if i is prime
        if (spf[i] == i):
              
            # marking SPF for all numbers
            # divisible by i
            for j in range(i * i, MAXN, i): 
                  
                # marking spf[j] if it is 
                # not previously marked
                if (spf[j] == j):
                    spf[j] = i
  
# A O(log n) function returning prime 
# factorization by dividing by smallest 
# prime factor at every step
def getFactorization(x):
    ret = list()
    while (x != 1):
        ret.append(spf[x])
        x = x // spf[x]
  
    return ret
  
# Driver code
  
# precalculating Smallest Prime Factor
sieve()
x = 12246
print("prime factorization for", x, ": ",
                                end = "")
  
# calling getFactorization function
p = getFactorization(x)
  
for i in range(len(p)):
    print(p[i], end = " ")
  
# This code is contributed 
# by Mohit kumar 29


C#
// C# program to find prime factorization of a
// number n in O(Log n) time with precomputation
// allowed.
using System;
using System.Collections;
  
class GFG
{
    static int MAXN = 100001;
      
    // stores smallest prime factor for every number
    static int[] spf = new int[MAXN];
      
    // Calculating SPF (Smallest Prime Factor) for every
    // number till MAXN.
    // Time Complexity : O(nloglogn)
    static void sieve()
    {
        spf[1] = 1;
        for (int i = 2; i < MAXN; i++)
      
            // marking smallest prime factor for every
            // number to be itself.
            spf[i] = i;
      
        // separately marking spf for every even
        // number as 2
        for (int i = 4; i < MAXN; i += 2)
            spf[i] = 2;
      
        for (int i = 3; i * i < MAXN; i++)
        {
            // checking if i is prime
            if (spf[i] == i)
            {
                // marking SPF for all numbers divisible by i
                for (int j = i * i; j < MAXN; j += i)
      
                    // marking spf[j] if it is not 
                    // previously marked
                    if (spf[j] == j)
                        spf[j] = i;
            }
        }
    }
      
    // A O(log n) function returning primefactorization
    // by dividing by smallest prime factor at every step
    static ArrayList getFactorization(int x)
    {
        ArrayList ret = new ArrayList();
        while (x != 1)
        {
            ret.Add(spf[x]);
            x = x / spf[x];
        }
        return ret;
    }
      
    // Driver code
    public static void Main()
    {
        // precalculating Smallest Prime Factor
        sieve();
        int x = 12246;
        Console.Write("prime factorization for " + x + " : ");
      
        // calling getFactorization function
        ArrayList p = getFactorization(x);
      
        for (int i = 0; i < p.Count; i++)
            Console.Write(p[i] + " ");
        Console.WriteLine("");
    }
}
  
// This code is contributed by mits


PHP


输出:

prime factorization for 12246 : 2 3 13 157 

注意:上面的代码适用于n达到10 ^ 7的量级。除此之外,我们还将面临内存问题。

时间复杂度:最小素数因子的预计算是使用筛子在O(n log log n)中完成的。就像在计算步骤中一样,我们每次都将数字除以最小的质数,直到它变成1。因此,让我们考虑一次SPF为2的最坏情况。因此将具有log n除法步骤。因此,我们可以说,在最坏的情况下,我们的时间复杂度将为O(log n)