Number Theory - prime number sieve Summary

Prime number sieve method has been my early learning problems, and now summarize it, prevent forgetting.

① Normal sieve O (n√n)

By definition, a certain number n combined can be obtained from multiplying the number of two, a factor of two greater than √N, √N less than another, it is possible to enumerate factor of from 2 to √N, can be determined whether n divisible, such as not divisible, for the prime.

② Erichsen sieve O (n㏒n)

If a number is prime, then his multiple is necessarily composite number, they can within a given range of his multiple first screened out, so we can open a tag array, to assume the starting state of all numbers are prime ( That is not marked). We will begin with n from 2 to enumerate, if not labeled, the number is a prime number, we then the number in the n-screen out all multiples of (labeled).

#include<bits/stdc++.h>
using namespace std;
int prime[50005],//储存素数
    flag[50005],//标记数组
    cot;//计数
int main()
{
    int n;
    cin>>n;
    for(int i=2;i<=n;i++)
    {
       if(!flag[i])//如未被标记,即是素数
       {
         prime[cot++]=i;//加入素数数组中
         for(int j=2*i;j<=n;j+=i)//将倍数都标记
         {
           flag[j]=1;
         }
       }
    }
//    printf("%d\n",cot);
//    for(int i=0;i<cot;i++)
//    {
//      printf("%d ",prime[i]);
//    }
return 0;
}

③ linear sieve (Eulerian mesh) O (n)

Because Erichsen sieve, some numbers are screening several times, such as 6, 2 and 3 have been sifted, so to be optimized to ensure that each number is only screen once. Euler screening method, we have carried out for each enumerator, and it has been the product of prime numbers to the screen, and in order to ensure that each number is not repeated weed out, if the number is divisible by the prime number may be have been, then that has been sifted.

#include<bits/stdc++.h>
using namespace std;
int prime[50005],//存素数
    flag[50005],//标记数组,是否被筛
    cot;
int main()
{
    int n;
    cin>>n;
    for(int i=2;i<=n;i++)
    {
       if(!flag[i])//如未被筛
       {
        prime[cot++]=i;//储存
       }
       for(int j=0;j<cot&&prime[j]*i<=n;j++)
       {
          flag[prime[j]*i]=1;//将倍数筛去
          if(i%prime[j]==0)//i这个数已被筛,跳出
            break;
       }
    }
//    printf("%d\n",cot);
//    for(int i=0;i<cot;i++)
//    {
//      printf("%d ",prime[i]);
//    }
return 0;
}

In fact, Erichsen screen, we find the outermost loop is a prime number, and then go from all of its multiple screens;
and Euler sieve, our outermost loop to enumerate the multiples fact, then, including loop layer and has been multiplied by a prime number, screens out larger multiples (here and in fact, similar to Eppendorf sieve, the sieve to a multiple of a prime number), and if (i% prime [j] == 0) break; this sentence ensures that each number is only screen once, thereby reducing the time complexity.

Guess you like

Origin www.cnblogs.com/Pecoz/p/12397323.html