zoukankan      html  css  js  c++  java
  • 素数筛法小结

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

    ① 普通筛法 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
    ",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
    ",cot);
    //    for(int i=0;i<cot;i++)
    //    {
    //      printf("%d ",prime[i]);
    //    }
    return 0;
    }
    
    

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

    戒骄戒躁,百炼成钢!
  • 相关阅读:
    java学习笔记(4)多态
    scala学习笔记(1)
    java复习(3)继承下
    java复习(3)继承
    java复习(2)
    java中常见的异常种类
    数组的内存结构
    Castle ActiveRecord学习(一)简介
    OAuth2.0 Owin 授权问题
    将对象转为json,加入到HttpResponseMessage中
  • 原文地址:https://www.cnblogs.com/Pecoz/p/12397323.html
Copyright © 2011-2022 走看看