Generating primes fast is very important in some problems.
Let's cut to the chase and introduce Eratosthenes's Sieve.
The main idea is the following. Suppose we want to find all primes between 2 and 50.
Iterate from 2 to 50. We start with 2. Since it is not checked, it is a prime number. Now check all numbers that are multiple of

Now check all numbers that are multiple of

Here's the implementation.
#include <stdio.h> int primechk[21000]; void preprocess(void) { int i, j; for(i=2 ; i<=20000 ; i++) { primechk[i]=1; } for(i=2 ; i<=20000 ; i++) { if(primechk[i]==1) { for(j=2 ; i*j<=20000 ; j++) { primechk[i*j]=0; } } } } int main(void) { preprocess(); int i, cnt=0; for(i=2 ; i<=20000 ; i++) { if(primechk[i]==1) { cnt++; printf("%d is the %dth prime!\n",i,cnt); } } }
Okay, so what is the time complexity? To get all primes in the interval
![$[1,n]$](https://latex.artofproblemsolving.com/2/2/4/2240bb122bdadbe086c0a6291dcd5a3eb82ad5cf.png)

Very very fast. To prove this, notice that the number of iterations are something like


Well, Merten's Second Theorem states that

Now we know how to generate prime numbers fast. How about primality testing?
Naive solutions first. Given an integer






Here's a "solution" in

I'll introduce the deterministic version. We probably (hopefully) won't see stuff like

Here's the sketch of the algorithm. Choose some set of



Decompose


![$$a^d \not\equiv 1 \pmod{n} \text{ and }a^{2^rd} \not\equiv -1 \pmod{n} \text{ for all } r \in [0,s-1]$$](https://latex.artofproblemsolving.com/7/4/a/74a345ba6ea049ecb21ece5794db740668f66d3e.png)



For


For


Now let us look at prime factorization of numbers.
Assume that we generated prime numbers using the Eratosthenes's Sieve.
If


Make another array. While we are doing the Sieve, for composite numbers, put "the first prime that verified that this number is composite" and for prime numbers, put itself. This is easy to implement.
Then we can start with

#include <stdio.h> int primechk[21000]; int fprime[21000]; void preprocess(void) { int i, j; for(i=2 ; i<=20000 ; i++) { primechk[i]=1; } for(i=2 ; i<=20000 ; i++) { if(primechk[i]==1) { fprime[i]=i; for(j=2 ; i*j<=20000 ; j++) { primechk[i*j]=0; if(fprime[i*j]==0) { fprime[i*j]=i; } } } } } int main(void) { preprocess(); int n; scanf("%d",&n); while(n!=1) { printf("%d\n",fprime[n]); n=n/fprime[n]; } }
If not, we can just check through all primes less than

If all the primes multiply up to



Another algorithm involving prime factorization is Pollard's rho algorithm - since the pseudocode is simple, I'll leave you the wikipedia link. https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm#Algorithm
Comments
Post a Comment