1.试除法判定质数–O(sqrt(N))
bool is_prime(int x)
{
if (x < 2) return false;
for (int i = 2; i <= x / i; i ++ )
if (x % i == 0)
return false;
return true;
}
2.试除法分解质因数–O(logN)~O(sqrt(N))
void divide(int x)
{
for (int i = 2; i <= x / i; i ++ )
if (x % i == 0)
{
int s = 0;
while (x % i == 0) x /= i, s ++ ;
cout << i << ' ' << s << endl;
}
if (x > 1) cout << x << ' ' << 1 << endl;
cout << endl;
}
3.埃氏筛法求质数–O(NloglogN)
int primes[N],cnt;
bool st[N];
//筛选出所有数的倍数
void get_primes(int n)
{
for (int i = 2; i <= n; i++)
{
if (st[i]) continue;
primes[cnt++] = i;
for (int j = i + i; j <= n; j += i) st[j] = true;//筛选出i的倍数
}
}
4.欧拉筛法O(N)
int i, j, num=1;
memset(u, true, sizeof(u));
for (i=2; i<=n; i++){ //顺序分析整数区间的每个数
if (u[i]) su[num++]=i; //将筛中最小数送入素数表
for (j=1; j<num; j++) { //搜索素数表的每个数
if (i*su[j]>n) break; //若i与当前素数的乘积超出范围,则分析下一个整数i
u[i*su[j]]=false; //将i与当前素数的乘积从筛子中筛去
if (i%su[j]==0) break; //若当前素数为i的最小素因子,则分析下一个整数i,这样可避免重复,降低时间复杂度
}
}
洛谷P3383 【模板】线性筛素数
题目描述
如题,给定一个范围
n
n
n,有
q
q
q 个询问,每次输出第
k
k
k 小的素数。
输入格式
第一行包含两个正整数
n
,
q
n,q
n,q,分别表示查询的范围和查询的个数。
接下来
q
q
q 行每行一个正整数
k
k
k,表示查询第
k
k
k 小的素数。
输出格式
输出
q
q
q 行,每行一个正整数表示答案。
输入输出样例 #1
输入 #1
100 5
1
2
3
4
5
输出 #1
2
3
5
7
11
说明/提示
【数据范围】
对于
100
%
100\%
100% 的数据,
n
=
1
0
8
n = 10^8
n=108,
1
≤
q
≤
1
0
6
1 \le q \le 10^6
1≤q≤106,保证查询的素数不大于
n
n
n。
#include<bits/stdc++.h>
int n, m;
const int N =1e8+1;
int a[N], primes[N];
void prime_sieve()
{
int i, j, t = 0;
for (i = 2; i <= n; i++)
{
if (a[i] == 0)
{
primes[++t] = i;
}
for (j = 1; j <= n / i&&i*primes[j]<=n; j++)
{
a[primes[j] * i] = 1;
if (i % primes[j] == 0)
{
break;
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
prime_sieve();
int i;
for (i = 1; i <= m; i++)
{
int x;
scanf("%d",&x);
printf("%d\n",primes[x]);
}
return 0;
}