素数筛法
素数筛法
埃式筛
思想
基本思想 :从2开始,将每个质数的倍数都标记成合数,以达到筛选素数的目的。
代码
const int maxn=100000005;
int prime[maxn],pnum=0;
bool p[maxn]={0};
int findprime(int n){
for(int i=2;i<=n;i++)
{
if(p[i]==false){
prime[pnum++]=i;
for(int j=i*i;j<=n;j+=i){
p[j]=true;
}
}
}
}
缺陷
对于一个合数,有可能被筛多次。例如 30 = 2 * 15 = 3 * 10 = 5*6……
思考
那么如何确保每个合数只被筛选一次呢?我们只要用它的最小质因子来筛选即可,这便是欧拉筛法。
欧拉筛
思想
基本思想 :在埃氏筛法的基础上,让每个合数只被它的最小质因子筛选一次,以达到不重复的目的。
代码
const int maxn=1000005;
int prime[maxn]={0},pnum=0;
bool a[maxn]={0};
void findprime(){
pnum=0;
for(int i=2;i<maxn;i++)
{
if(a[i]==0)
{
prime[pnum++]=i;
}
for(int j=0;j<pnum&&i*prime[j]<maxn;j++)
{
a[i*prime[j]]=true;
if(i%prime[j]==0)
{
break;
}
}
}
}
详解
将i的(素数)倍数都变为true,如果i能被已知素数整除,则break(因为下一个素数肯定能整除i,比如6能被2整除,也能被3整除,所以在被2整除后break),如果a[i]==0直接放入素数,每个i都需要经过第二层for循环。
- 2是素数
- 4(2*2)不是素数
- 3是素数
- 6(2*3)不是素数
- 9(9*3)不是素数
- 4不是素数
- 8(4*2)不是素数(brek)
......
- 8(4*2)不是素数(brek)

浙公网安备 33010602011771号