素数:仅能被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;
        }
    }
}

 

  

posted on 2020-04-18 09:28  新望  阅读(195)  评论(0编辑  收藏  举报