【Number Theory】| Judging prime numbers, decomposing prime factors, Ehrlich sieve, linear sieve

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++),

  1. 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.

  2. If x is a prime number, it either i<=x/iquits directly due to dissatisfaction , or keeps performing a no-operation, and loops until dissatisfaction i<=x/iand 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*xas 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 :

  1. If i%primes[j]==0, then primes[j]==x, it is the smallest prime factor of i, so it primes[j]must be primes[j]*ithe smallest prime factor.
  2. If i%primes[j]!=0, then primes[j]all prime factors less than i, therefore, primes[j]must be primes[j]*ithe smallest prime factor. (Because it primes[j]is enumerated from small to large)

Of course, there are also restrictions on the primes[j] of the enumeration, that is

  1. primes[j]*iIt must be less than or equal to n, so as to st[primes[j]*i]=true;prevent crossing the boundary. It is written in the same way as determining prime numbers primes[j]<=n/i.
  2. primes[j]The subscript j of must meet the conditions j<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.

  1. 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;
  2. 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]*imay 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; //找到了最小质因子,后面就不用再筛了,退出
        }
    }
}

Guess you like

Origin blog.csdn.net/HangHug_L/article/details/114753184