51 nod 1256 乘法逆元

2019-04-14 21:01发布

例如: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; }