数学知识-质数

1.质数的定义:大于1的并且只能被1或自己整除的树就是质数。小于等于1的既不是质数也不是合数;

2.判断质数:

a.埃拉托斯特尼筛法,简称埃氏筛 或 爱氏筛,是一种由希腊数学家埃拉托斯特尼所提出的一种简单检定素数的算法。 要得到自然数n以内的全部素数,必须把不大于根号n的所有素数的倍数剔除,剩下的就是素数。 要得到自然数n以内的全部素数,必须把不大于 的所有素数的倍数剔除,剩下的就是素数。

简而言之:就是把素数的倍数的数 全部剔除掉 剩下的数就是素数。

void Eratosthenes_Sieve(int n, bool a[]{
    //寻找不超过n的所有质数,数组a用来存放结果,用a[i]==0表示a是合数
    memset(a,0,sizeof(bool)*(n+1));//清零
    a[0]=a[1]=1;//0和1需要特殊标记
    for(int i=2;i*i<=n;i++)
        if(a[i]==0) //如果i未被之前的数筛去说明i是质数
            for(int j=i<<1;j<=n;j+=i)
                a[j]=1;//筛去i的所有倍数i*j
}

b.欧拉筛:又称线性筛。在埃氏筛的基础上(也是用素数的倍数去筛掉非素数 ,合数只能被它的最小质因数来筛,比如20 ,只能用它的最小质因数2来筛除,不能用4,或者5去筛除)不同于埃氏筛的是 欧拉筛不会重复筛一个数 从而降低了时间的复杂度。

int pri[N+9>>1],now;
bool vis[N+9];
void init(){
    for(int i=2;i<=N;i++){
        if(!vis[i])pri[++now]=i;
        for(int j=1;j<=now&&pri[j]*i<=N;j++){
            vis[pri[j]*i]=1;
            if(i%pri[j]==0)break;
        }
    }
}

c.试除法,从2开始到sqrt(n)一个个除过去

bool is_prime(int n)
{
    if (n < 2) return false;
    for (int i = 2; i <= n / i; i ++ )//i*i<=n可能会溢出导致结果错误,i<=sqrt(n)较慢
        if (n % i == 0)
            return false;
    return true;
}

3.分解质因数:例如输入n,求n!所有的质因子及个数

void divide(int x)
{
    for (int i = 2; i <= x / i; i ++ )
        if (x % i == 0)
        {
            int s = 0;
            while (x % i == 0) x /= i, s ++ ;
            cout << i << ' ' << s << endl;
        }
    if (x > 1) cout << x << ' ' << 1 << endl;
    cout << endl;
}

例题:P3383 【模板】线性筛素数 P1835 素数密度

你可能感兴趣的:(算法)