例如:4关于1模7的乘法逆元为多少?
4X≡1 mod 7
这个方程等价于求一个X和K,满足
4X=7K+1
其中X和K都是整数。
若ax≡1 mod f, 则称a关于模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
说明5与14互素,存在5关于14的乘法逆元。
1=5-4=5-(14-5*2)=5*3-14
因此,5关于模14的乘法逆元为3。
其求法可用
欧几里德算法:
Extended Euclid (d,f) //算法求d关于模f的乘法逆元d
-1 ,即 d* d
-1 mod
f = 1
1 。(X1,X2,X3) := (1,0,f); (Y1,Y2,Y3) := (0,1,d)
2。 if (Y3=0) then return d
-1 = null //无逆元
3。 if (Y3=1) then return d
-1 = Y2 //Y2为逆元
4。 Q := X3 div Y3 //整除
5。 (T1,T2,T3) := (X1 - Q*Y1,X2 - Q*Y2,X3 - Q*Y3)
6 。(X1,X2,X3) := (Y1,Y2,Y3)
7。 (Y1,Y2,Y3) := (T1,T2,T3)
8。 goto 2
常用于加密算法中,如仿射算法。
#include
#include
#include
using namespace std;
//返回d=gcd(a,b);和对应于等式ax+by=d中的x,y
long long extend_gcd(long long a, long long b, long long &x, long long &y){
if(a == 0 && b == 0)
return -1;//无最大公约数
if(b == 0){
x = 1;
y = 0;
return a;
}
long long d = extend_gcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
//*********求逆元素*******************
//ax = 1(mod n)
long long mod_reverse(long long a, long long n){
long long x, y;
long long d = extend_gcd(a, n, x, y);
if(d == 1)
return (x % n + n) % n;
else
return -1;
}
int main(){
long long n, m;
while(~scanf("%d%d", &m, &n)){
printf("%lld
", mod_reverse(m, n));
}
return 0;
}