数学知识——质数

什么是质数:
在大于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
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);
}

你可能感兴趣的:(数学知识,算法)