埃氏筛 
筛到一个质数后,把它所有的倍数全部删去。非常简单易懂。
复杂度 O ( n log  log  n ) O(n \log \log n) O ( n log  log  n )  。 (证明略去)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 bool  prime[N];void  solve (int  n)  {     for (int  i=2 ;i<=n;i++)prime[i]=1 ;     for (int  i=2 ;i<=n;i++){         if (!prime[n])continue ;                                    for (int  j=i*i;j<=n;j+=i){             prime[j]=0 ;         }     } }
 
线性筛(欧氏筛) 
埃氏筛的效率还是不够高,我们尝试构建一个复杂度为 O ( n ) O(n) O ( n )   的筛法。
线性筛的思路是对于一个数 (不一定是质数),筛掉它的一些质数倍(质数倍的质数应该小于它的最小值质因数)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 int  v[N]; int  prime[N];int  cnt=0 ;void  solve (int  n)  {     for (int  i=2 ;i<=n;i++){         if (v[i]==0 ){             v[i]=i;             prime[++cnt]=i;         }         for (int  j=1 ;j<=cnt;j++){                          if (prime[j]>v[i] || i*prime[j] > n){                 break ;             }             v[i*prime[j]]=prime[j];         }     } }
 
在线性筛中,一个合数会且仅会被筛一遍,并且是被它的最小质因数筛掉的。
我们来证明一下为什么一个合数会且仅会被筛一遍:
先证至少会被筛一遍:
考虑合数 N = p 1 p 2 … p n N = p_1 p_2 \dots p_n N = p 1  p 2  … p n   (设 p 1 ≤ p 2 ≤ ⋯ < p n p_1 \le p_2 \le \dots <p_n p 1  ≤ p 2  ≤ ⋯ < p n   )。
则在循环到合数 N 0 = p 2 p 3 … p n N_0 = p_2 p_3 \dots p_n N 0  = p 2  p 3  … p n    时,一定会在第二重循环中循环到 p 1 p_1 p 1    (因为合数 p 2 … p n p_2 \dots p_n p 2  … p n    的最小质因数为 p 2 p_2 p 2   ,p 1 ≤ p 2 p_1 \le p_2 p 1  ≤ p 2   ,循环不会跳出)
 
只会被筛一遍
那么,会不会一个合数被筛了很多次呢?你可能会有疑问,合数 N = p 1 p 2 … p n N = p_1 p_2 \dots p_n N = p 1  p 2  … p n   (p 1 ≤ p 2 ≤ ⋯ ≤ p n p_1 \le p_2 \le \dots \le p_n p 1  ≤ p 2  ≤ ⋯ ≤ p n   )会不会在之前 循环到合数 N 1 = p 1 p 3 p 4 … p n N_1 = p_1 p_3 p_4 \dots p_n N 1  = p 1  p 3  p 4  … p n    时先把它乘上 p 2 p_2 p 2   ,把 N N N   筛了两次呢?(此时等号 p 1 = p 2 p_1=p_2 p 1  = p 2    无法取到,因为 N 1 ≠ N 0 N_1 \neq N_0 N 1   = N 0   )
这是不会的,因为 N 1 N_1 N 1    的最小值因数是 p 2 p_2 p 2   ,而 p 2 > p 1 p_2 > p_1 p 2  > p 1   ,循环已经跳出了。这就是我们写的 prime[j]>v[i] 条件的作用。
 
 
例题 
求出区间 [ L , R ] [L,R] [ L , R ]   之间的整数中,相邻质数的差最小值和最大值。
数据范围:1 < L < R < 2 31 1 < L < R < 2^{31} 1 < L < R < 2 31  ,R − L ≤ 1 0 6 R-L \le 10^6 R − L ≤ 1 0 6  。
样例输入:1 11
样例输出:1 4 (2 和 3 差 1,7 和 11 差 4)
首先,筛出 2 ∼ R 2\sim\sqrt{R} 2 ∼ R    中所有的质数。
然后将 L ∼ R L\sim R L ∼ R   范围内这些质数的倍数全部删去即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 #include <bits/stdc++.h>  using  namespace  std;const  int  N = 1e6 +5 ;int  cnt=0 ;int  v[N];int  prime[N];void  init (int  n)  {     for (int  i=2 ;i<=n;i++){         if (v[i]==0 ){             v[i]=i,prime[++cnt]=i;         }         for (int  j=1 ;j<=cnt;j++){             if (v[i]<prime[j] || i*prime[j]>n){                 break ;             }             v[i*prime[j]]=prime[j];         }     } }bool  x[N];int  main ()  {     int  l,r;     scanf ("%d%d" ,&l,&r);     init (sqrt (r));     for (int  i=1 ;i<=cnt;i++){         for (int  j=max (2 ,l/prime[i]);prime[i]*j<=r;j++){             x[j*prime[i]-l]=1 ;         }     }     int  maxn = -1 ;     int  minn = INT_MAX;     int  last=-1 ;     for (int  i=0 ;i<=r-l;i++){         if (x[i])continue ;         if (last==-1 ){last=i;continue ;}         maxn = max (maxn,i-last);         minn = min (minn,i-last);         last = i;     }     printf ("%d %d\n" ,minn,maxn);     return  0 ; }
 
素数定理 
设 π ( x ) \pi(x) π ( x )   为不超过 x x x   的素数个数,则有如下近似:
π ( x ) ∼ x ln  x \pi(x)\sim\dfrac{x}{\ln x}
 π ( x ) ∼ ln x x  
以下是一张素数个数表格,供参考:
n n n  
π ( n ) \pi(n) π ( n )  
n ln  n \dfrac{n}{\ln n} ln n n   
 
 
1 0 2 10^2 1 0 2  
25 25 25  
22 22 22  
 
1 0 3 10^3 1 0 3  
168 168 168  
145 145 145  
 
1 0 4 10^4 1 0 4  
1229 1229 1229  
1086 1086 1086  
 
1 0 5 10^5 1 0 5  
9592 9592 9592  
8686 8686 8686  
 
1 0 6 10^6 1 0 6  
78498 78498 78498  
72382 72382 72382  
 
1 0 7 10^7 1 0 7  
664579 664579 664579  
620421 620421 620421  
 
1 0 8 10^8 1 0 8  
5761455 5761455 5761455  
5428681 5428681 5428681