什么是质数:
在大于1的整数中,只包含1和本身这两个约数的整数称为质数,也称为素数。
##求质数
1.试除法求质数
初步想法是,可以从2~n-1之间遍历一遍,若其中存在除了1和自身的数能整除n,则说明n不是质数——时间复杂度O(n)
bool prime(int n)
{
if(n < 2) return 0;
for(int i = 2; i <= n; i ++)
if(n % i == 0)
return 0;
return 1;
}
当然我们可以进一步优化:
若d能整除整数n,则n/d也能整除整数n,表示为 d | n, ( n / d ) | n。
令 d <= n / d,则在 2 到 d 之间,能找到可以把n整除的数,则说明 n 不是质数——时间复杂度O(sqrt(n))
#include<cstdio>
bool prime(int n)
{
if(n < 2) return 0;
for(int i = 2; i <= n / i; i ++)
if(n % i == 0)
return 0;
return 1;
}
2.埃氏筛
给出整数 n ,从整数1 ~ n 开始,删去所有能被第 i 个整数整除的整数,若第 n 个数没有被前 2 ~ (n - 1) 的数整除,则说明 n 是质数,
const int N = 100100;
bool st[N];
int prime[N], cnt;
void prime(int n)
{
for(int i = 2; i <= n; i ++)
{
if(!st[i]) prime[cnt++] = i;
for(int j = i + i; j <= n; j += i)
st[j] = 1;
}
}
3.线性筛
给出整数 n, i 为 1 ~ n 的整数,prime[j] <= n / i;
若 i % prime[j] == 0 , 而prime[j] < i ,说明 prime[j] 是 i 的最小质因数,则 i * prime[j] 的最小质因数为 prime[j];
若 i % prime[j] != 0, 而prime[j] < i,则 prime[j] 不是 i 的最小质因子,prime[j] 是 i * prime[j] 的最小质因数
由此可说明每个合数都只能被它的最小质因数删掉。
由于每个数只能被筛掉一次,所以时间复杂度为O(n)
const int N = 1000010;
bool st[N];
int prime[N], cnt;
void get_prime(int n)
{
for(int i = 2; i <= n; i ++)
{
if(!st[i]) prime[cnt ++] = i;
for(int j = 0; prime[j] < n / i; j ++)
{
st[i * prime[j]] = 1;
if(i % prime[j] == 0)
break;
}
}
4.试除法求质因数
原理:算数基本定理
void divide(int n)
{
for(int i = 2; i <= n / i; i ++)
{
if(n % i == 0)
{
int s = 0;
while(n % i == 0)
{
s ++;
n /= i;
}
printf("%d %d\n", i, s);
}
}
if(n > 1) printf("%d 1\n", n);
}