如果一个数无法被除了1和自身外的任何自然数整除,那么就称这个数为质数。
一般情况下对于一个足够大的整数N,不超过N的质数大约有
N
/
l
n
(
N
)
N/ln(N)
N/ln(N)个,即每
l
n
(
N
)
ln(N)
ln(N)个数中大约有一个质数(《算法竞赛进阶指南》上写的,我不会证明)。
比较无脑的判断质数的方法为试除法:
写一个 f o r for for循环,从 2 2 2到 n − 1 n-1 n−1都 M o d Mod Mod一下,若都不等于 0 0 0,则说明这个数为质数。
试除法稍微聪明一点的话:
写一个
f
o
r
for
for循环,从
2
2
2到
n
2
\sqrt[2]{n}
2n(虽说书上是这么写,但我一般
M
o
d
Mod
Mod到
n
2
+
1
\sqrt[2]{n}+1
2n+1)都
M
o
d
Mod
Mod一下,若都不等于
0
0
0,则说明这个数为质数。
而要直接筛出一个区间的的话,当然是选择
E
r
a
t
o
s
t
h
e
n
e
s
Eratosthenes
Eratosthenes筛法(埃氏筛)或者线性筛(欧拉筛)更快一点,这里直接讲线性筛
int v[maxn],prime[maxn];
int getprimes(int n)
{
int m=0;
for(int y=2;y<=n;y++)
{
if(v[y]==0) {v[y]=y;prime[++m]=y;}
for(int i=1;i<=m;i++)
{
int x=prime[i];
if(x>v[y]) break;
if(x*y>n) break;
int z=x*y;
v[z]=x;
}
}
return m;
}
直接筛出来
1
1
1到
n
n
n之间的质数,共有
m
m
m个(不包括
1
1
1)
若
v
[
i
]
=
=
i
v[i]==i
v[i]==i,则
i
i
i为质数
p
r
i
m
e
[
i
]
prime[i]
prime[i]存的是
1
1
1到
m
m
m中的第
i
i
i个质数
因为一个数的因数只能是比自己小的,而
2
2
2是最小的质数,所以从
2
2
2开始
然后找到
v
[
2
]
=
=
0
v[2]==0
v[2]==0表示2没有因数,所以就
v
[
2
]
=
2
v[2]=2
v[2]=2
p
r
i
m
e
[
+
+
m
]
=
y
prime[++m]=y
prime[++m]=y,第一个质数为
2
2
2
然后进入循环,所有下标是
2
2
2的倍数的都是
2
2
2
这样的话第
n
n
n个数如果有因数则
v
[
n
]
v[n]
v[n]等于这个因数
否则为
0
0
0
为
0
0
0时表示是质数
例题:
∙
\bullet
∙ 素数个数
∙
\bullet
∙ 【模板】线性筛素数
∙
\bullet
∙ UVA10140 Prime Distance
算术基本定理
任何一个大于1的正整数都能唯一分解为有限个质数的乘积,可写为:
N
=
p
1
c
1
p
2
c
2
p
3
c
3
…
p
m
c
m
N=p^{c_1}_1p^{c_2}_2p^{c_3}_3…p^{c_m}_m
N=p1c1p2c2p3c3…pmcm
其中
c
i
c_i
ci都是正整数,
p
i
p_i
pi都是质数,且满足
p
1
<
p
2
<
…
p
m
p_1<p_2<…p_m
p1<p2<…pm