模运算以及乘法逆元
基本的模运算
a,b,p 均为整数
模 p 加法:
模 p 减法:
模 p 乘法:
同余式:正整数 a,b 对 p 取模,它们的余数相同,记作
基本性质
1. 若 p=a-b, 则
2. 传递性:若
运算规则
结合律
交换律
分配律
重要定理
乘法逆元
定义
如果 ax≡1 (mod p), 且 gcd (a,p)=1(a 与 p 互质),则称 a 关于模 p 的乘法逆元为 x。
例子
例如:4 关于 1 模 7 的乘法逆元为多少?
4X≡1 mod 7
这个方程等价于求一个 X 和 K,满足
4X=7K+1
其中 X 和 K 都是整数。
若 ax≡1 (mod f), 则称 a 关于 1 模 f 的乘法逆元为 x。也可表示为 ax≡1 (mod f)。
当 a 与 f 互素时,a 关于模 f 的乘法逆元有解。如果不互素,则无解。如果 f 为素数,则从 1 到 f-1 的任意数都与 f 互素,即在 1 到 f-1 之间都恰好有一个关于模 f 的乘法逆元。
例如,求 5 关于模 14 的乘法逆元:
14=5*2+4
5=4*1+1
说明 5 与 14 互素,存在 5 关于 14 的乘法逆元。
1=5-4=5-(14-5*2)=5*3-14
因此,5 关于模 14 的乘法逆元为 3。
扩展欧几里得定理
欧几里得算法 (辗转相除法)
即以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数
证明
引理 1:若 d 是 a 和 b 的公约数,那么 d 也是 b 和 c 的公约数(c=a% b)
引理 2:若 d 是 b 和 c 的公约数 (c=a% b) 那么 d 也是 b 和 c 的公约数
定理:两个整数的最大公约数等于其中较小的那个数和两数相除余数的最大公约数。
证法:
a 可以表示成
假设 d 是 a,b 的一个公约数,记作
而
因此 d 也是 b,a mod b 的公约数
因 (a,b) 和 (b,a mod b) 的公约数相等,则其最大公约数也相等
1 | def gcd(a,b): |
时间复杂度为 O (log n)
本体
设两个式子
所以
而
其中 k=[a/b]
所以有
展开移项得:
根据对应系数关系,可以设
递归地使用 x'、y' 表示 “上一步” 的 x、y,就能递归地把问题转化为
算法
对于任意两个整数 a, b,必存在整数 x, y,使得 ax + by = gcd (a,b) 成立,求出整数解 x, y,可以得到 gcd (a,b).
具体步骤
1. 定义 x1 = 1, y1 = 0, x2 = 0, y2 = 1
2. 若 b ≠ 0,使用带余除法,用 b 除以 a 得到余数 r;否则转到第 4 步
3. 用 b 代替 a, 用 r 代替 b, 令 x1, y1, x2, y2 = x2, y2, x1 - q·x2, y1 - q·y2,重复第 2 步
4.a 的值就是最大公约数 d,x1 和 y1 的值就是所求 x 和 y
代码实现
1 | def exgcd(a,b): |
模拟矩阵运算的扩展欧几里得算法:https://www.cnblogs.com/kentle/p/14975039.html
求逆元
逆元:a 关于模 b 得逆元整数 d 满足
扩展欧几里得:求方程
关系:
设 d 为 x,-k 为 y,则
求出 x 即可得到 a 关于模 b 的逆元
当 x 为负值的时候
代码实现
1 | def exgcdinv(a,b): |
时间复杂度为 O (log n)(斐波那契复杂度)
补充
1. 显然,当 x 求出负值时,由于乘法逆元应为正,经验证,若
2.python 自带的 pow 函数 pow (a,b,c),当 b 为 - 1 的时候,可以求 a 关于模 c 的乘法逆元
存在即可求
费马小定理
前置知识
费马小定理
对于整数 a 与质数 b,若 a 与 b 互质,则有
快速幂取模
两数之积取模等于对两数分别取模然后对积取模
代码实现
1 | def powmod(a,n,mod): |
求逆元
显然
用 b-2 和 b 代替快速幂取模中的 n 和 mod:
1 | def Fermatinv(a,b): |
时间复杂度:大约 O (log b)
适用范围:在模数 b 是质数时
Stein 算法
只有整数的移位和加减法,便于大素数求公约数
前置知识
算法步骤
假设 A1=A,B1=B,C1=1
for n=1,2,3...do:
1. 若 An=0 或 Bn=0,则 max (An,Bn)*Cn 为最大公约数,算法结束
2. 若 An 和 Bn 均为偶数,则 An+1= 若 An/2,Bn+1=Bn/2,Cn+1=2*Cn
3. 若 An 为偶数,Bn 为奇数,则 An+1=An/2,Bn+1=Bn
4. 若 An 为奇数,Bn 为偶数,则 An+1=An,Bn+1=Bn/2
5. 若 An,Bn 均为奇数,则 An+1=|An-Bn|/2
Bn+1=min(An,Bn),Cn+`=Cn
代码实现
1 | def Stein(a,b): |