zoukankan      html  css  js  c++  java
  • 算法模板-素数判断/素数筛法

    素数:仅能被1和它本身整除的数叫做素数,否则是合数。

    素数判断:一个数n,将所有小于n大于1的数逐个带入,如果有任意一个能整除,判断是合数,如果都不能,是素数。

    优化:一个合数的因子是成对出现的(假设n=i*j;i<j;当我们判断i是n的一个因子时,同时也判断了j是n的一个因子),所以我们不必判断从2到n-1的所有数,判断2到sqrt(n)即可。

    bool isprim(unsigned x)
    {
        if(x<2)return false;
        for(unsigned i=2;i*i<=x;i++)
            if(x%i==0)return false;
        return true;
    }

    有时候,程序里需要反复检查一个数是否为素数,可以把判断结果保存在数组里,方便查询。这就是素数的筛法。

    埃氏筛法:O(n log n),筛选出不是素数的数。有的数会被重复筛选,比如12:2*6=3*4=12;所以12会被2和3筛选到。

    const int maxn=1000009;
    bool noprime[maxn];
    void isprim()
    {
        memset(noprime,0,sizeof(noprime));
        noprime[0]=noprime[1]=1;
        for(int i=2;i*i<maxn;i++)
            if(!noprime[i])
                for(int j=i*i;j<maxn;j+=i)
                    noprime[j]=true;
    }

     欧拉筛/线性筛:O(n),利用质因数分解,任何一个整数都有他唯一的质因数表示法,所以就保证了每个数只被筛选一次。

    const int maxn=100009;
    int prime[maxn+1];            //prime[0]用来储存素数个数 
    void getPrime()
    {
        memset(prime,0,sizeof(prime));
        for(int i=2;i<=maxn;i++){
            if(!prime[i])prime[++prime[0]]=i;
            for(int j=1;j<=prime[0]&&prime[j]*i<=maxn;j++){
                prime[prime[j]*i]=1;
                if(i%prime[j]==0)break;
            }
        }
    }

      

  • 相关阅读:
    VS Code 的常用快捷键
    oj教程--坑
    oj教程--学习顺序
    oj教程--链表
    oj教程--队列
    oj教程--栈
    【MySQL】汇总数据
    【MySQL】使用WHERE子句
    【MySQL】SELECT语句
    【MySQL】使用MySQL(连接、选择数据库、显示数据库和表信息)
  • 原文地址:https://www.cnblogs.com/xinwang-coding/p/12724153.html
Copyright © 2011-2022 走看看