`算法知识` 质数, 取模, GCD最大公约数, 上取整/下取整/向0取整, 质因数分解

本文深入探讨了算法中的取模运算,详细解释了不同类型的取整方式,并讨论了质数的相关性质,包括质数合数、质数个数、质因数分解等。此外,还介绍了最大公约数(GCD)算法及其与取模的关系,以及如何高效地判断质数和实现质因数分解算法。
摘要由CSDN通过智能技术生成

定理

定理一: k, g为任意整数, d为任意 不为g的倍数, 则: k*g + d一定不是 g的倍数.
… 即一个数a, (他的倍数) + (不是他的倍数) = (不是他的倍数)
… (但, k + d可能是g的倍数. 比如: 2 + 3 = 5)

定理二:
a % b = a − ⌊ a b ⌋ ∗ b a \% b = a - {\lfloor \frac{a}{b} \rfloor} * b a%b=abab, 该公式非常常用!
a % b = ( k 1 % k 2 ) ∗ g = ( k 1 − ⌊ k 1 k 2 ⌋ ∗ k 2 ) ∗ g a \% b = (k1 \% k2) * g = ( k1 - {\lfloor \frac{k1}{k2} \rfloor} * k2) * g a%b=(k1%k2)g=(k1k2k1k2)g
g = gcd(a,b), a=k1*g, b=k2*g
注意, 这里的下取整, 是严格的下取整, 不是 (计算机的向0取整), 因为 我们定义%为: 非负取模
… 比如, -5 % 2 = 1 = -5 - (-5/2) * 2, 显然这个-5 / 2应该等于-3, 不是向零取整.
… 除非你把%定义为 (向0取模: 正数正模, 负数负模),
计算机在进行a%b时, 就是执行的 a - (a/b)*b, 因为(计算机的/是: 向0取整的除法), 因此, 计算机的取模, 是(向0取模)

取模

计算机中的取模%, 本质是:

Ll_ Mod( Ll_ _a, Ll_ _b){
   
    return _a - Divide( _a, _b) * _b;
}

这也是根据的定理二.
你可以当做是: a % b, 就调用了这个函数.

因此, 研究%的行为 (是非负取模, 还是非正取模, 还是向0取模), 就必须研究 整除/的行为

Divide整数的取整, 分类有: (向0取整 cpp默认) (向下取整) (向上取整)

  • 一般, 模数都会是正数.
    因此, 我们这里只考虑: b > 0 b > 0 b>0的情况. ( b如果是0, 是非法的, 除0错误)
    … 这里多说一句, 如果Divide是 (向0取整), 则有:Divide( a, -b) == -1 * Divide( a, b)
    … 也就是意味着, 此时Mod( a, b) 恒等于 Mod( a, -b)
    … 因为: Divide( a, -b) = -1 * Divide( a, b), 但这只发生在 Divide是 (向0取整)的情况
    … 比如: 5 / 2 = 2 5 / -2 = -2 (这个性质很重要, 可能计算机使用(向0取整), 是因为他)
    … 但是, 当Divide是 (向上/ 向下取整)时, Divide( a, -b) = -Divide( a, b)并不成立.
    … 比如: (下取整: 5 / 2 = 2 5 / -2 = -3) (上取整: 5 / 2 = 3 5 / -2 = -2
    总之, 以下分析中, 都假设b > 0

  • Divide是 (向0取整)时, 此时, Mod呈现的是: (向0取模)
    m = a % b: (如果a >= 0, 则m = [0, b)) (否则a < 0, 则m = (-b, 0]) 从那个公式可推出
    比如: 5 % 2 = 1 -5 % 2 = -1, 有正有负

  • Divide是 (向下取整)时, 此时, Mod呈现的是: (正取模)
    m = a % b: (不管a是正负, 都会有 m = [0, b)) 从那个公式可推出
    比如: 5 % 2 = 1 -5 % 2 = 1, 全部为正

  • Divide是 (向上取整)时, 此时, Mod呈现的是: (负取模)
    m = a % b: (不管a是正负, 都会有 m = (-b, 0]) 从那个公式可推出
    比如: 5 % 2 = -1 -5 % 2 = -1, 全部为负

上, 下, 向0取整 的代码

//> 向0整除
Ll_ Divide( Ll_ _a, Ll_ _b){
   
    return _a / _b; 
}

//> 向上取整
Ll_ Divide( Ll_ _a, Ll_ _b){
   
    return ( _a + ( _b - 1)) / _b;
}

//> 向下取整
Ll_ Divide( Ll_ _a, Ll_ _b){
   
//* 下取整, 暂时还没想到更简洁的算法.
//* 目前的做法是:  如果结果为正 或 可以整除, 则使用(向0取整); 否则, 向0取整 - 1
//* 这里的`结果`, 是指的`a/b`这个结果 是个小数 精确的指. 不是整除.
//* 但肯定不是: 类似上取整的`return ( _a - ( _b - 1)) / _b`, 不要理想当然
    if( ( _a >= 0 && _b >= 0)
            || ( _a <= 0 && _b <= 0)){
   
        return _a / _b;
    }
    if( _a 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值