判断质数与筛质数
一:判定质数
要判断一个数是不是质数,只需遍历小于等于它的所有数,如果它能被除了1和本身之外的数整除,那么它就不是质数。
很简单,暴力枚举,代码如下:
1 bool is_prime(int x) 2 { 3 if (x < 2) return false; 4 for (int i = 2; i < x ; i ++ ) 5 if (x % i == 0) 6 return false; 7 return true; 8 }
但是还可以优化,对于一个数$x$,它有一个约数$d$,那么$\frac{x}{d}$也是$x$的约数,所以我们只需要枚举较小的一个就可以了,即$d <\frac{x}{d}$ ,即我们只需枚举到$\sqrt{x}$即可。
1 bool is_prime(int x) 2 { 3 if (x < 2) return false; 4 for (int i = 2; i <= x / i; i ++ ) 5 if (x % i == 0) 6 return false; 7 return true; 8 }
时间复杂度就从原本的$O(n)$降为了$O(\sqrt{n})$。
二:分解质因数
由上面,我们知道$x$中最多只包含一个大于$\sqrt{x}$的质因子,如果有两个就大于$x$了,矛盾。所以我们先枚举小于等于$\sqrt{x}$的质因子,再特判一下大于$\sqrt{x}$的质因子即可。代码如下:
1 void solve(int n){ 2 for(int i = 2; i <= n / i ; i ++) 3 { 4 if( n % i == 0){ 5 int s = 0; 6 while(n % i == 0){ 7 n /= i; 8 s ++; 9 } 10 cout << i << " " << s << endl; 11 } 12 } 13 if(n != 1)cout << n << " " << 1 << endl; 14 }
三:(1)筛法求质数
思想是,将$2\sim n$之间的数枚举,从前往后,依次将每一个数的倍数筛掉,用一个$primes$数组存储质数,代码如下:
1 void get_primes(int n) 2 { 3 for (int i = 2; i <= n; i ++ ) 4 { 5 if (st[i]) continue; 6 primes[cnt ++ ] = i; 7 for (int j = i; j <= n; j += i) 8 st[j] = true; 9 } 10 }
当$i = 2$,循环$\frac{n}{2}$次, 当$i = 3$ ,循环$\frac{n}{3}$次。所以一共循环$\frac{n}{2}+\frac{n}{3}+\frac{n}{4}+\cdot \cdot \cdot \frac{n}{n}=n\left ( \frac{1}{2}+\frac{1}{3}+\frac{1}{4}+\cdot \cdot \cdot +\frac{1}{n} \right )$,当$n$趋于无穷时,调和级数趋于$lnn + c$。
所以该算法的时间复杂度为$O(nlogn)$。这个复杂度是计算将每一个数的倍数筛掉的时间复杂度,而代码中的只将素数的倍数筛掉的复杂度会更低一些,为$O(nloglogn)$。
($1 \sim n$ 中有$\frac{n}{lnn}$个素数)。
(2)线性筛法:
1 void get_primes(int n) 2 { 3 for (int i = 2; i <= n; i ++ ) 4 { 5 if (!st[i]) primes[cnt ++ ] = i; 6 for (int j = 0; primes[j] <= n / i; j ++ ) 7 { 8 st[primes[j] * i] = true; 9 if (i % primes[j] == 0) break; 10 } 11 } 12 }
将每一个质数加入,然后该质数去筛掉该质数的倍数。当$i \;mod\; primes[j] == 0$时,$primes[j]$一定是$i * primes[j]$的最小质因子,也一定是$i$的最小质因子。当$i \;mod\; primes[j] != 0$时,说明$primes[j]$小于$i$的所有质因子,所以$primes[j]$也一定是$primes[j] * i$的最小质因子。对于一个合数$x$,假设$primes[j]$是他的最小质因子,当$i$枚举到$\frac{x}{primes[j]}$的时候,($\frac{x}{primes[j]}$一定比$x$先枚举到),$x$就会在循环内被筛掉。由于每一个数只有一个最小质因子,所以是线性的。

浙公网安备 33010602011771号