逆元,除法同余原理

🎬 博主名称个人主页

🔥 个人专栏 : 《算法通关》

⛺️心简单,世界就简单

引言

这篇其实是寒假时候的一个博弈论问题,里面设计到了逆元,除法同余原理,我的补题内容,但是一种拖,现在当存稿补充一下发了

在组合数学或算法题中,我们常会遇到需要对含有除法的表达式取模的情况。然而,与加、减、乘法不同,除法在模运算下并不遵循简单的规则。如果不加处理,直接对除法的中间结果取模,将得到错误的答案。

加减乘的同余原理

在处理涉及模运算(取余运算)的算法问题时,加、减、乘法遵循直观且一致的运算规则,这使得我们可以在运算过程中安全地进行取模操作,从而有效防止大数溢出,并简化计算。

核心规则

设模数为 mod(一个正整数),对于整数 ab,以下规则成立:

  1. 加法同余规则
    (a % mod + b % mod) % mod = (a + b) % mod

    这意味着:两个数相加再取模的结果,等于它们各自取模后相加,再对和取模的结果。

  2. 减法同余规则
    (a % mod - b % mod) % mod = (a - b) % mod

    这意味着:两个数相减再取模的结果,等于它们各自取模后相减,再对差取模的结果。

    注意 :由于编程语言中 % 运算对负数的处理方式,为确保结果落在 [0, mod-1] 的非负范围内,当 (a % mod - b % mod) 为负数时,通常需要加上一个 mod 进行调整。

  3. 乘法同余规则
    (a % mod) * (b % mod) % mod = (a * b) % mod

    这意味着:两个数相乘再取模的结果,等于它们各自取模后相乘,再对积取模的结果。


除法同余原理

一、问题引入:为什么不能直接对除法取模?

考虑计算 (10 / 5) % 3。实际结果为:

  1. 10 / 5 = 2

  2. 2 % 3 = 2

但如果直接对分子和分母分别取模:

  1. 10 % 3 = 1

  2. 5 % 3 = 2

  3. (1 / 2) % 3 = 0

显然 0 ≠ 2,结果错误。这是因为除法不满足同余定理的直接推广。


二、解决方案:引入乘法逆元

要解决这个问题,我们需要引入乘法逆元的概念。其核心思想是:在模运算中,将除法转换为乘法。

关键转换

在模 MOD 意义下,计算 (a / b) % MOD 等价于计算:
(a * inv(b)) % MOD

其中 inv(b)b 在模 MOD 意义下的乘法逆元,满足:
(b * inv(b)) % MOD = 1

换句话说,inv(b) 在模 MOD 意义下起到了 1/b 的作用。


三、使用乘法逆元的前提条件

要使上述转换成立,必须满足以下三个条件:

  1. 整除性a / b 必须为整数(即 a 能被 b 整除)。

  2. 模数为质数MOD 必须是质数(例如常见的 1000000007)。

  3. 互质条件bMOD 必须互质(即最大公约数为1)。

在实际问题中,条件2和3通常由题目保证,条件1则需要我们在设计算法时自行确保。


四、如何计算乘法逆元?

MOD 为质数时,根据费马小定理b 的乘法逆元可以通过快速幂计算:
inv(b) = b^(MOD-2) % MOD

计算示例

5 在模 3 意义下的逆元:
inv(5) = 5^(3-2) % 3 = 5^1 % 3 = 2

验证:(5 * 2) % 3 = 10 % 3 = 1,满足逆元定义。


五、实战应用:对除法进行模运算

现在我们可以正确计算 (10 / 5) % 3

  1. 计算 5 的逆元:inv(5) = 2

  2. 计算 (10 * inv(5)) % 3 = (10 * 2) % 3 = 20 % 3 = 2

这与直接计算 (10 / 5) % 3 = 2 的结果一致。

关键优势:可对中间结果取模

当处理大数时,例如计算组合数 C(100, 50),其分子分母的阶乘(如 100!)会远远超过 long long 的范围。通过逆元将除法转换为乘法,我们可以在每一步都进行取模运算,避免数值溢出。

转换后的计算方式:
(a / b) % MOD = ((a % MOD) * (b^(MOD-2) % MOD)) % MOD

这样,即使 ab 很大,我们也可以安全地计算。


六、关于指数运算的说明

你可能会担心 b^(MOD-2) 的指数很大(例如 MOD=1000000007)。实际上,我们可以通过快速幂算法O(log MOD) 时间内高效计算,并在计算过程中不断取模,确保不会溢出。

七、总结与记忆要点

当题目满足以下条件时:

  1. 需要计算 (a / b) % MOD

  2. MOD 是质数(如 1000000007

  3. bMOD 互质

  4. a 能被 b 整除

我们可以按以下步骤计算:

  1. 计算 b 的逆元:inv(b) = b^(MOD-2) % MOD

  2. 计算最终结果:(a % MOD) * inv(b) % MOD

核心公式
(a / b) % MOD = (a % MOD) * (b^(MOD-2) % MOD) % MOD

记住这个公式,你就可以在算法竞赛中安全地处理除法取模问题了。


补充说明:在实际编程中,通常会将逆元计算封装为函数,并利用快速幂算法高效求解。这样既能保证正确性,又能应对大规模数据。

cpp 复制代码
long power(long b,int n,int mod){
	long ans=1;
	while(n>0){
		if((n&1)==1){
			ans=(ans*b)%mod;
		}
		b=(b*b)%mod;
		n>>=1;
	}
	return ans;
} 

下面是除法同余原理

cpp 复制代码
long power(long b,int n,int mod){
	long ans=1;
	while(n>0){
		if((n&1)==1){
			ans=(ans*b)%mod;
		}
		b=(b*b)%mod;
		n>>=1;
	}
	return ans;
} 
int f(long a,long b,int mod){
	long inv =power(b,mod-2,mod);
	return (int)(((a%mod)*inv)%mod);
}
相关推荐
2301_765703149 分钟前
C++中的职责链模式实战
开发语言·c++·算法
StandbyTime17 分钟前
《算法笔记》学习记录-第一章
c++·算法·算法笔记
近津薪荼22 分钟前
优选算法——双指针8(单调性)
数据结构·c++·学习·算法
格林威23 分钟前
Baumer相机铆钉安装状态检测:判断铆接是否到位的 5 个核心算法,附 OpenCV+Halcon 的实战代码!
人工智能·opencv·算法·计算机视觉·视觉检测·工业相机·堡盟相机
星空露珠1 小时前
速算24点检测生成核心lua
开发语言·数据库·算法·游戏·lua
happygrilclh1 小时前
高压高频电源的pid算法
算法
格林威1 小时前
Baumer相机铸件气孔与缩松识别:提升铸造良品率的 6 个核心算法,附 OpenCV+Halcon 实战代码!
人工智能·opencv·算法·安全·计算机视觉·堡盟相机·baumer相机
葫三生2 小时前
存在之思:三生原理与现象学对话可能?
数据库·人工智能·神经网络·算法·区块链
Evand J2 小时前
【MATLAB例程】无人机三维路径规划|A*,RRT(快速随机树算法), APF(人工势场法)算法对比|可自定义起终点、障碍物坐标。附下载链接
算法·matlab·无人机·astar·路径规划·rrt·apf
少许极端2 小时前
算法奇妙屋(二十七)-全排列与子集问题
算法·剪枝·回溯·递归