模运算的基本性质

模运算(Modular Arithmetic)是数论中的一个重要概念,在密码学、计算机科学和工程领域有广泛应用。以下是模运算的主要性质:

基本定义

对于整数a、b和正整数m,我们说a与b模m同余,记作:

a≡b(modm)

当且仅当m整除(a - b),即存在整数k使得:

a−b=km

基本性质

算术运算性质

重要定理

模逆元

模逆元定义

应用实例

模指数运算(快速幂算法):

def mod_exp(base, exp, mod):
    result = 1
    base = base % mod
    while exp > 0:
        if exp % 2 == 1:
            result = (result * base) % mod
        exp = exp >> 1
        base = (base * base) % mod
    return result

模逆元计算(扩展欧几里得算法):

def mod_inverse(a, m):
    g, x, y = extended_gcd(a, m)
    if g != 1:
        return None  # 逆元不存在
    else:
        return x % m

模运算的这些性质在密码学(如RSA、Diffie-Hellman)、哈希算法、随机数生成和错误检测编码(如CRC)等领域都有重要应用。

模运算(Modular Arithmetic)是数论中的基础工具,在C++编程中广泛应用于防止整数溢出、哈希计算、组合数学、密码学等领域。掌握其性质可以让我们更高效、安全地进行取模操作。 以下是模运算的核心性质及其在C++中的应用解释。 --- ### ✅ 一、基本定义 对于整数 $ a $、正整数 $ m $,有: $$ a \bmod m = r \quad \text{其中 } 0 \leq r < m, \text{ 且 } a = qm + r $$ 例如:$ 17 \bmod 5 = 2 $ --- ### ✅ 二、模运算的代数性质(设 $ a, b, c \in \mathbb{Z} $, $ m > 0 $) | 性质 | 公式 | 说明 | |------|------|------| | **加法封闭性** | $ (a + b) \bmod m = [(a \bmod m) + (b \bmod m)] \bmod m $ | 可先对每个加数取模再相加 | | **减法封闭性** | $ (a - b) \bmod m = [(a \bmod m) - (b \bmod m) + m] \bmod m $ | 减法可能为负,需加 $ m $ 调整 | | **乘法封闭性** | $ (a \times b) \bmod m = [(a \bmod m) \times (b \bmod m)] \bmod m $ | 关键!用于“边乘边模” | | **幂运算** | $ a^k \bmod m = \left[(a \bmod m)^k\right] \bmod m $ | 快速幂的基础 | --- ### 🔍 三、详细解释与C++实现 #### 1. 加法取模 ```cpp (a + b) % MOD == ((a % MOD) + (b % MOD)) % MOD ``` ✅ 应用场景:累加和防溢出 ```cpp long long sum = 0; for (int i = 0; i < n; i++) { sum = (sum + arr[i]) % MOD; } ``` > ⚠️ 注意:即使 `arr[i]` 很大,也要先 `% MOD` 再加。 --- #### 2. 减法取模(关键:处理负数) 直接 `(a - b) % MOD` 可能为负! ```cpp // 安全的减法取模 long long sub = ((a % MOD) - (b % MOD) + MOD) % MOD; ``` ✅ 解释:加 `MOD` 确保结果非负。 例如:$ (3 - 7) \bmod 5 = (-4 + 5) \bmod 5 = 1 $ --- #### 3. 乘法取模(最重要) ```cpp (a * b) % MOD == ((a % MOD) * (b % MOD)) % MOD ``` ✅ 这就是“边乘边取模”的理论依据! ```cpp long long prod = 1; for (int i = 1; i <= n; i++) { prod = (prod * i) % MOD; // 防止阶乘溢出 } ``` > ❗如果不这样做,`prod` 很快会超过 `long long` 范围。 --- #### 4. 幂运算取模 利用快速幂(二分幂): ```cpp long long mod_pow(long long base, long long exp, long long mod) { long long res = 1; base %= mod; while (exp > 0) { if (exp & 1) res = (res * base) % mod; base = (base * base) % mod; exp >>= 1; } return res; } ``` 基于性质: $$ a^k \bmod m = \left((a \bmod m)^k\right) \bmod m $$ --- ### ✅ 四、其他重要性质 | 性质 | 公式 | 条件 | |------|------|------| | **分配律** | $ (a + b) \bmod m = (a \bmod m + b \bmod m) \bmod m $ | 恒成立 | | **结合律** | $ ((a + b) \bmod m + c) \bmod m = (a + (b + c) \bmod m) \bmod m $ | 成立 | | **交换律** | $ (a + b) \bmod m = (b + a) \bmod m $ | 成立 | | **除法?** | ❌ 不成立!不能直接除 | 必须用**模逆元** | --- ### 🚫 五、模运算中不能直接做的操作 #### ❌ 错误:$ (a / b) \bmod m \neq (a \bmod m) / (b \bmod m) $ 必须使用**模逆元**(Modular Inverse)代替除法。 若 $ b $ 与 $ m $ 互质(如 $ m $ 是质数且 $ b \not\equiv 0 \pmod{m} $),则存在唯一 $ b^{-1} $ 满足: $$ b \cdot b^{-1} \equiv 1 \pmod{m} $$ 于是: $$ (a / b) \bmod m = (a \cdot b^{-1}) \bmod m $$ 👉 使用费马小定理(当 $ m $ 为质数): $$ b^{-1} \equiv b^{m-2} \pmod{m} $$ ```cpp long long inv_b = mod_pow(b, MOD - 2, MOD); long long div = (a * inv_b) % MOD; ``` --- ### ✅ 六、常见模数选择 - $ 10^9+7 $:最常用的大质数,适合做模数 - $ 998244353 $:NTT 友好型质数,形如 $ 2^k \cdot c + 1 $ - 选择质数是为了保证模逆元存在(除了倍数外) --- ### ✅ 七、实际应用场景总结 | 场景 | 用到的模运算性质 | |------|------------------| | 阶乘取模 | 乘法性质,边乘边模 | | 组合数 $ C(n,k) \bmod p $ | 阶乘 + 逆元 | | 快速幂 | 幂运算 + 乘法性质 | | 哈希函数 | 多项式取模:$ (s_0 \cdot b^{n-1} + \cdots) \bmod m $ | | 动态规划状态压缩 | 所有运算都要取模防溢出 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值