我们可以计算O(sqrt(n))中的数字“ n”的素因式分解,如此处所述。但是,当我们需要回答有关素因数分解的多个查询时,O(sqrt n)方法会超时。
在本文中,我们研究了一种使用O(n)空间和O(log n)时间复杂度并允许每次计算的方法来计算质因数分解的有效方法。
先决条件: Eratosthenes筛,直到n的数字的最小素因数。
Key Concept: Our idea is to store the Smallest Prime Factor(SPF) for every number. Then to calculate the prime factorization of the given number by dividing the given number recursively with its smallest prime factor till it becomes 1.
为了计算每个数字的最小素因数,我们将使用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) 。