素数算法(埃氏筛法 &&欧拉筛法)

埃氏筛法:
整数的唯一分解定理:
任何一个大于1的自然数 N,如果N不为质数,都可以唯一分解成有限个质数的乘积N=P1 ^ a1 · P2 ^ a2 · P3 ^ a3 · … · Pn ^ an ,这里P1<P2<P3<…<Pn均为质数,其诸指数 ai 是正整数。

bool vis[maxN];

void init()
{
    memset(vis,false, sizeof(vis));//所有数初始化为0->质数
    vis[0]=true;
    vis[1]=true;
}

void Is_Prime()
{
    init();
    for(int i=2;i<=N;i++)
    {
        if(!vis[i])
            for(int j=i*i;j<=N;j+=i)
                vis[j]=true;
    }
}

C++ 语言默认就有 bool 及 true 和 false。C 语言默认只有 _Bool 及 0 和 1 值,在 include 标准库 <stdbool.h> 后才变成 bool 及 true 和 false。

埃氏筛法无法避免重复地筛一些数,比如说30=2 * 15=3 * 10=5 * 6,所以为了避免重复筛数,我们有线性筛!
线性筛(欧拉筛法)
线性筛是在埃氏筛法的基础上,让每一个合数,只被它的最小质因子筛选一次,达到不重复的目的。
怎么理解呢?根据最开始所说的整数的唯一分解定理,每个合数有且只有一组质数相乘可以得到,前面的埃氏筛法,每一个质因子都要筛掉该合数一次,我们如果让每个合数只被它最小的质因子筛选就完全避免了埃氏筛法的重复。从算法来说,N范围内的每个数都只会被筛一次,所以算法复杂度是O(n)。

bool vis[maxN];
int prime[maxN],cnt;

void init()
{
    memset(vis,false, sizeof(vis));//所有数初始化为0->质数
    vis[0]=true;
    vis[1]=true;
    cnt=0;
}

void Is_Prime()
{
    init();
    for(int i=2;i<=N;i++)
    {
        if(!vis[i])//i是质数
            prime[++cnt]=i;//prime是用来存质数的数组,显然数组中的质数是从小到大
        for(int j=1;j<=cnt;j++)
        {
            if(i*prime[j]>N)//超出了范围
                break;
            vis[i*prime[j]]=true;
            if(i % prime[j] == 0)//跑到了i的最小的质因数
                break;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值