1. Trial division method to determine prime numbers
bool isPrime(int x)
{
if (x<2) return false;
for (int i=2;i<=x/i;i++)
if (x%i==0) return false;
return true;
}
2. Decompose prime factors
void divide(int x)
{
for (int i=2;i<=x/i;i++) {
//找当前的x的大于等于i的质数
if (x%i==0) {
//i从2开始,满足条件x%i为0的i一定都是质数,合数肯定不符合条件
int s=0;
while (x%i==0) s++,x/=i; //去除掉x的质因子i,所以x不再包含2~i之间的质因子了
printf("%d %d\n",i,s); //输出i^s
}
}
if (x>1) printf("%d %d\n",x,1);//最后剩下的x要么是个质数,要么是个1
puts("");
}
for (int i=2;i<=x/i;i++)
In this process, x is constantly getting smaller. When the loop reaches i, x does not contain prime numbers between 2 and i-1, so what we are looking for is the prime number of x that is greater than or equal to i.
x is for the changed x under each for loop. According to the nature n中最多只含有一个大于sqrt(n)的质因子
, if this i is greater than sqrt(x), you can exit directly, because we have changed x from 2 to i-1, that is, 2 to sqrt(x) The prime numbers in between have been found, so **the last remaining x has only two cases,** either it is the only prime number that is greater than the sqrt(x) of x at the initial data input, or it does not exist , The remaining x is a 1.
In the for loop
for (int i=2;i<=x/i;i++)
,
If x is a composite number, because the prime numbers between 2 and i-1 are not factors of x, then i or a number greater than i is his factor, then x must be greater than i^2, so the cycle will continue.
If x is a prime number, it either
i<=x/i
quits directly due to dissatisfaction , or keeps performing a no-operation, and loops until dissatisfactioni<=x/i
and quit.
The composite number x will eventually become smaller and become a prime number x or 1 greater than sqrt(x).
3. Sieve prime number
3.1 Elbow sieve
Naive approach:
void getPrimes(int n)//求1到n之间的质数
{
for (int i=2;i<=n;i++) {
if(!st[i]) primes[cnt++]=i;
for (int j=i+i;j<=n;j+=i) st[j]=true; //对于每个i,k*i都是合数,置为true (k>=2)
}
}
But when a number is a composite number, n×m, there is no need to set its multiple to a composite number, because as early as the prime number n or the prime number m, the number of the multiple speed of n×m has been set to a composite number. The number of multiples of n×m is the sum of the multiples of n is a subset of the numbers of multiples of m .
Elbow sieve:
Initialize first, think that all numbers are prime numbers, and then **every find a prime number x,** classify the composite number that is a multiple of the prime number k*x
as a composite number.
int primes[N],cnt;//存储质数,cnt是下标
bool st[N];//st[i]为false说明i质数
void getPrimes(int n)//求1到n之间的质数
{
for (int i=2;i<=n;i++)
if(!st[i]) {
//获得质数i,并把k*i置成合数
primes[cnt++]=i;
for (int j=i+i;j<=n;j+=i) st[j]=true; //k*i都是合数,置为true (k>=2)
}
}
The time complexity of the Ehrlich sieve is O(nlogn) . There is a case where a composite number is n×m. When a prime number n is encountered, m×n is set to a composite number when k=m; when a prime number m is encountered , When k=n, n×m will be set to a composite number. Both are the same number, that is, there will be repeated screening .
3.2 Linear screen
The core of linear sieve : every composite number will only be sifted out by its smallest prime factor , so it will only be sifted once.
For each i that is enumerated, suppose its smallest prime factor is x, and primes[0]
find x (including x) in the prime number table from the beginning, and the ones in between primes[j]
are less than or equal to x. Satisfy the nature :
- If
i%primes[j]==0
, thenprimes[j]==x
, it is the smallest prime factor of i, so itprimes[j]
must beprimes[j]*i
the smallest prime factor. - If
i%primes[j]!=0
, thenprimes[j]
all prime factors less than i, therefore,primes[j]
must beprimes[j]*i
the smallest prime factor. (Because itprimes[j]
is enumerated from small to large)
Of course, there are also restrictions on the primes[j] of the enumeration, that is
primes[j]*i
It must be less than or equal to n, so as tost[primes[j]*i]=true;
prevent crossing the boundary. It is written in the same way as determining prime numbersprimes[j]<=n/i
.primes[j]
The subscript j of must meet the conditionsj<cnt
.
In fact, it is fine to limit 2. The largest prime number we use is the prime number i itself, and the primes array has recorded all prime numbers between 2 and i.
- When i is a composite number, its smallest prime factor must be less than i, and our primes array has recorded all prime numbers between 2 and i-1;
- When i is a prime number, its smallest prime factor is itself, and we have already put it into the primes array in advance, so when i is a prime number, it is the maximum traversal situation, and the entire primes array will be traversed.
Therefore, restriction 2 is not required, but restriction 1 is necessary because it primes[j]*i
may be out of bounds.
int primes[N],cnt;
bool st[N];//st[i]为false说明i质数
void getPrimes(int n)//求1到n之间的质数
{
for (int i=2;i<=n;i++) {
if (!st[i]) primes[cnt++]=i;
//找i的最小质因子
for (int j=0;primes[j]<=n/i;j++) {
st[primes[j]*i]=true;
if (i%primes[j]==0) break; //找到了最小质因子,后面就不用再筛了,退出
}
}
}