C++数学-数论筛质数经典OJ题流食般投喂

先做题自己思考,再看解析呦~


OJ题来源:洛谷

OJ题名:素数密度

OJ题归属:数学-数论【筛质数】

解题算法:线性筛、埃氏筛

🐻算法原理:

🐻借助素数的判定中用试除法从 1,sqrt r 进行试除的原理,在筛质数里面,我们可以用 1,sqrt r 中的质数去筛掉 l,r 里面的合数。

🐻在对区间 l,r 进行筛质数时,要合理映射下标~

🐻筛质数时,我们要从质数的 "合理倍数" 那个数开始筛。

🦓题目细节:

🦓测试用例会给 L == 1,但是 1 既不是质数也不是合数,要特判,给 1 的话,要映射到 2.

🦓筛质数时,"合理倍数" 不能是 1 倍,那样就要筛去质数本身了。特判,最小倍数得是 2 倍。

cpp 复制代码
#include<iostream>
#include<cmath>

using namespace std;

typedef long long LL;

const int N = 1e6 + 10;

int l, r;
bool st[N];
int p[N], cnt;
bool ret[N];

void get_prime()
{
	int n = sqrt(r);
	for (int i = 2; i <= n; i++)
	{
		if (!st[i]) p[++cnt] = i;
		for (int j = 1; 1ll * i * p[j] <= n; j++)
		{
			st[i * p[j]] = true;
			if (i % p[j] == 0) break;
		}
	}
}

int main()
{
	cin >> l >> r;
    
    // 细节 1
	l = l == 1 ? 2 : l;

	get_prime();

	for (int i = 1; i <= cnt; i++)
	{
		LL x = p[i];
        // 细节 2
		for (LL j = max((l + x - 1) / x * x, 2 * x); j <= r; j += x)
		{
			ret[j - l] = true;
		}
	}

	int sum = 0;
	for (int i = l; i <= r; i++)
	{
		if (!ret[i - l]) sum++;
	}

	cout << sum << endl;

	return 0;
}

OJ题来源:洛谷

OJ题名:Goldbach's Conjecture (哥德巴赫猜想)

OJ题归属:数学-数论【筛质数】

解题算法:线性筛

🐻算法原理:

🐻先用线性筛筛出题目指定范围的质数;

🐻两个质数差值最大,就是遍历 p数组 从小质数到大质数遍历,第一个符合题目条件的就是两个差值最大的质数,如何判断,n - a = b,看看 b 这个质数有没有被标记上,没有就是质数,stn - a = false。

cpp 复制代码
#include<iostream>
#include<cstring>

using namespace std;

typedef long long LL;

const int N = 1e6 + 10;

int n;
bool st[N];
int p[N], cnt;

// 预处理出质数
void get_prime()
{
	for (LL i = 2; i <= 1e6; i++)
	{
		if (!st[i]) p[++cnt] = i;
		for (LL j = 1; i * p[j] <= 1e6; j++)
		{
			st[i * p[j]] = true;
			if (i % p[j] == 0) break;
		}
	}
}

int main()
{
	get_prime();

	while (cin >> n, n != 0)
	{
		bool flag = false;
		int x = 0, y = 0;
		for (int i = 2; i <= cnt; i++)
		{
			int a = p[i], b = -1;
			if (st[n - a] == false) // 关键特判
			{
				flag = true;
				b = n - a;
				x = a, y = b;
				break;
			}
		}

		if (flag == false) cout << "Goldbach's conjecture is wrong." << endl;
		else cout << n << " = " << x << " + " << y << endl;
	}

	return 0;
}