ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

数论-素数筛法小结

2020-03-02 18:59:27  阅读:171  来源: 互联网

标签:筛法 标记 int 筛去 素数 倍数 小结


素数筛法一直是我前期学习的难题,现在把它总结一下,防止忘记。

① 普通筛法 O(n√n)

根据定义,一个合数n一定可以由两个数相乘得到,这两个因数一个大于√n,另一个小于√n,所以可以对因数从2到√n进行枚举,判断是否可以被n整除,如无法整除,则为素数。

② 埃氏筛法 O(n㏒n)

如果一个数是素数,那么他的倍数就一定是合数,就可以在给定范围内将他的倍数先筛掉,所以我们可以开一个标记数组,先假定开始所有数的状态都是素数(即未被标记)。首先我们从2到n开始枚举,如未被标记,则该数为素数,我们再将该数在n内的所有倍数筛掉(标记)。

#include<bits/stdc++.h>
using namespace std;
int prime[50005],//储存素数
    flag[50005],//标记数组
    cot;//计数
int main()
{
    int n;
    cin>>n;
    for(int i=2;i<=n;i++)
    {
       if(!flag[i])//如未被标记,即是素数
       {
         prime[cot++]=i;//加入素数数组中
         for(int j=2*i;j<=n;j+=i)//将倍数都标记
         {
           flag[j]=1;
         }
       }
    }
//    printf("%d\n",cot);
//    for(int i=0;i<cot;i++)
//    {
//      printf("%d ",prime[i]);
//    }
return 0;
}

③线性筛法(欧拉筛) O(n)

因为在埃氏筛法中,有的数被筛了多次,如6,都被2和3筛过,所以要进行优化,保证每个数只被筛了一次。在欧拉筛法中,我们对每个数都进行枚举,将它与已得到的素数的乘积筛去,而为了保证每个数不重复筛去,如果该数可以被已得到素数整除,那么说明已被筛过。

#include<bits/stdc++.h>
using namespace std;
int prime[50005],//存素数
    flag[50005],//标记数组,是否被筛
    cot;
int main()
{
    int n;
    cin>>n;
    for(int i=2;i<=n;i++)
    {
       if(!flag[i])//如未被筛
       {
        prime[cot++]=i;//储存
       }
       for(int j=0;j<cot&&prime[j]*i<=n;j++)
       {
          flag[prime[j]*i]=1;//将倍数筛去
          if(i%prime[j]==0)//i这个数已被筛,跳出
            break;
       }
    }
//    printf("%d\n",cot);
//    for(int i=0;i<cot;i++)
//    {
//      printf("%d ",prime[i]);
//    }
return 0;
}

其实在埃氏筛中,我们最外层循环是找到素数,然后从再将其所有倍数筛去;
而在欧拉筛中,我们的最外层循环其实就枚举了倍数,然后再在内层循环中与已得到素数相乘,筛去更大的倍数(其实这里就与埃氏筛类似,将素数的倍数筛去),而 if(i%prime[j]==0) break; 这句确保了每个数只被筛一次,以此降低了时间复杂度。

标签:筛法,标记,int,筛去,素数,倍数,小结
来源: https://www.cnblogs.com/Pecoz/p/12397323.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有