欧拉质数筛
理解
是目前几乎最优的找质数方法,
例题_1
例题链接:https://www.acwing.com/problem/content/870/
给定一个正整数 n,请你求出 1∼n 中质数的个数。
题解
#include<bits/stdc++.h>
using namespace std;
int n;
//标记数组,标记合数
int mk[100000008];
//记录质数
int mem[1000006];
int idx , cnt;
void prime(int n)
{
for(int i = 2 ; i <= n ; i++)
{
//没有被标记,说明是质数,标记并记录
if(mk[i] == 0)
{
cnt++;
mk[i] = i;
mem[++idx] = i;
}
for(int j = 1 ; j <= idx ; j++)
{
//如果超出题目要求范围
if(mem[j] * i > n || mem[j] > mk[i])
{
break;
}
//质数 * 非0非1数字 = 合数,标记
mk[i * mem[j]] = mem[j];
}
}
}
int main()
{
cin >> n;
prime(n);
cout << cnt << endl;
return 0;
}
例题_2
例题链接:https://www.luogu.com.cn/problem/P3383
给定一个范围 n,有 q 个询问,每次输出第 k 小的素数
题解
#include<bits/stdc++.h>
using namespace std;
int n;
//标记数组,标记合数
int mk[100000008];
//记录质数
int mem[1000006];
int idx;
//欧拉质数筛
void prime(int n)
{
for(int i = 2 ; i <= n ; i++)
{
//没有被标记,说明是质数,标记并记录
if(mk[i] == 0)
{
mk[i] = i;
mem[++idx] = i;
}
for(int j = 1 ; j <= idx ; j++)
{
//如果超出题目要求范围
if(mem[j] * i > n || mem[j] > mk[i])
{
break;
}
//质数 * 非0非1数字 = 合数,标记
mk[i * mem[j]] = mem[j];
}
}
}
int main()
{
cin >> n;
prime(n);
int q;
cin >> q;
while(q--)
{
int k;
cin >> k;
cout << mem[k] << endl;
}
return 0;
}

浙公网安备 33010602011771号