【数论】质数相关代码模板

质数

1、试除法判断质数

bool is_prime(int x)  // 判定质数
{
    if (x < 2) return false;
    for (int i = 2; i <= x / i; i ++ )
        if (x % i == 0)
            return false;
    return true;
}
/*
这里使用"i <= x / i"是防止"i*i"太大超过int范围,
注意要使用等于号"=",防止质数的平方这种数
*/

2、试除法分解质因数

由算数基本定理可得:对于每个大于1的正整数n,存在一组质数p1, p2, …, pk,以及对应的正整数指数e1, e2, …, ek,使得n = p1e1 * p2e2 * … * pkek。 同时,这种表示方式是唯一的,即如果存在另一组质数q1, q2, …, qm,以及对应的正整数指数f1, f2, …, fm,使得n = q1f1 * q2f2 * … * qmfm,那么这两组质数和指数必须完全相同。根据这一原理我们可以使用试除法分解质因数。

备注:循环里面的 i 一定是一个质数:假如 i 是一个合数,那么它一定可以分解成多个质因子相乘的形式,这多个质因子同时也是 a 的质因子且比 i 要小,而比 i 小的数在之前的循环过程中一定是被条件除完了的,所以 i 不可能是合数,只可能是质数.

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;
}

3、筛质数

(1)普通筛

int const N = 1e7;
int primes[N]{0};
bool st[N]{0};
int cnt=0;
void get_primes(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(!st[i]) primes[cnt++]=i;//把素数存起来
        for(int j=i;j<=n;j+=i)//不管是合数还是质数,都用来筛掉后面它的倍数
        {
            st[j]=true;
        }
    }
}

(2)埃氏筛

int const N = 1e7;
int primes[N]{0};
bool st[N]{0};
int cnt=0;
void get_primes(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(!st[i])
        {
            primes[cnt++]=i;
            for(int j=i;j<=n;j+=i) st[j]=true;//可以用质数就把所有的合数都筛掉;
        }
    }
}

(3)线性筛

int const N = 1e7;
int primes[N]{0};
bool st[N]{0};
int cnt=0;
void get_primes(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(!st[i]) primes[cnt++]=i;
        for(int j=0;primes[j]<=n/i;j++)	//只筛选比n小的合数
        {
            st[primes[j]*i]=true;      //只用最小质因子去筛合数 
            if(i%primes[j]==0) break;
        }
    }
}
/*
	当i%primes[j]!=0时,
	说明此时遍历到的primes[j]不是i的质因子,
	那么只可能是此时的primes[j]<i的最小质因子,
	所以primes[j]*i的最小质因子就是primes[j];
	当有i%primes[j]==0时,
	primes[j]*i的最小质因子也就应该是prime[j]
	之后接着用st[primes[j+1]*i]=true去筛合数时,
	就不是用最小质因子去更新了,
	因为i有最小
	质因子primes[j]<primes[j+1],
	此时的primes[j+1]不是primes[j+1]*i的最小质因子,
	此时就应该退出循环
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想要AC的dly

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值