质数筛法:朴素素数筛,埃氏筛,欧式筛

简介: 质数筛法:朴素素数筛,埃氏筛,欧式筛

若一个数可以进行因数分解,则得到的两个数一定是有一个>=sqrt(x),另一个<=sqrt(x).

朴素算法

这个算法是最简单的素数判断算法+遍历素组,耗时长


bool judge(ll x)
{   
    if(x==2) return true;
    if(x<2||x%2==0)
        return false;   
    for(int i=3;i<=sqrt(x+1);i+=2)//这个地方可以优化一下,一个是范围,一个是步长 (素数一定是奇数) 
        {
            if(x%i==0)
                return false;
        }
    return true;
}

埃氏筛

利用当前已经找到的素数,从后面的数中筛去当前素数的倍数,当前素数已经是筛去数的质因子,如此下去能筛除之后所有的合数,是一种比较快的筛法

美中不足是会筛除多次比如8和16,同时被2和4筛去


36.png

输入数据

100 2

2

91

输出数据

Yes

No

#include <bits/stdc++.h>
using namespace std;
int prime[10000005];
const int N = 10000000;
void isprime()
{
    fill(prime,prime + N,true);
    prime[1] = false;
    for(int i = 2; i <= N; ++i)
    {
        if(prime[i])
        {
            for(int j = i * 2;j <= N;j += i)
            {
                prime[j] = false;
            }
        }
    }
}
int main()
{
    isprime();
    int n,m;
    cin>>n>>m;
    int num;
    for(int i = 0;i < m;i++)
    {
        cin>>num;
        if(prime[num])
            cout<<"Yes\n";
        else
            cout<<"No\n";
    }
    return 0;
}

欧式筛

这是一种很好的线性筛法,和埃氏筛法的区别是对于每一个要筛除的数,欧拉筛法只筛除一次。原理如下

任何一个合数都可以表示成一个质数和一个数的乘积

假设A是一个合数,且A = x * y,这里x也是一个合数,那么有:

A = x * y; (假设y是质数,x合数)

x = a * b; (假设a是质数,且a < x——>>a<y)

-> A = a b y = a Z (Z = b y)

即一个合数(x)与一个质数(y)的乘积可以表示成一个更大的合数(Z)与一个更小的质数(a)的乘积,那样我们到每一个数,都处理一次,这样处理的次数是很少的,因此可以在线性时间内得到解。

#include <bits/stdc++.h>
using namespace std;
int prime[10000005];
int primesize = 0;
bool isprime[10000005];
void getlist(int listsize)
{
    memset(isprime,1,sizeof(isprime));
    isprime[1] = false;
    for(int i = 2;i <= listsize;i++)
    {
        if(isprime[i])
        {
            prime[++primesize] = i;
        }
        for(int j = 1;j <= primesize && i * prime[j] <= listsize;j++)
        {
            isprime[i * prime[j]] = false;
            if(i%prime[j] == 0)
                break;
        }
    }
}
int main()
{
    int n,m;
    cin>>n>>m;
    getlist(n);
    int num;
    for(int i = 0;i < m;i++)
    {
        cin>>num;
        if(isprime[num])
        {
            cout<<"Yes"<<endl;
        }
        else
        {
            cout<<"No"<<endl;
        }
    }
    return 0;
}
相关文章
|
机器学习/深度学习 算法
【算法基础】筛质数
【算法基础】筛质数
70 0
筛质数、分解质因数和快速幂的应用
筛质数、分解质因数和快速幂的应用
70 0
|
6月前
|
机器学习/深度学习 资源调度 算法
杜教筛
【6月更文挑战第9天】
31 2
|
7月前
|
算法 测试技术 C++
【数学归纳法 组合数学】容斥原理
【数学归纳法 组合数学】容斥原理
迭代法解决递推问题:数列和,sinx,ex的近似值
迭代法解决递推问题:数列和,sinx,ex的近似值
126 0
一个求公约数和公倍数的有趣求法
一个求公约数和公倍数的有趣求法
66 0
每日一题——有序数组的平方
每日一题——有序数组的平方
|
存储
欧拉筛&&埃氏筛
欧拉筛&&埃氏筛
105 0
每日一题1021:迭代法求平方根
题目描述: 用迭代法求 平方根 公式:求a的平方根的迭代公式为: X[n+1]=(X[n]+a/X[n])/2 要求前后两次求出的差的绝对值少于0.00001。 输出保留3位小数
171 0

热门文章

最新文章