扩展欧几里得
扩展欧几里得即求方程 ax + by = gcd(a,b) 的整数解的算法。常用来求解逆元,即 ax = 1(mod b) -> ax % b = 1 -> ax - by = 1; 令b = -b,即
ax + by = 1,当a,b互质时有 ax + by = gcd(a,b);
求解过程:
根据欧几里得算法,当b!=0时,gcd(a,b) == gcd(b,a%b);
所以 ax + by = gcd(b,a%b); -> bx` + (a%b)y` = gcd(b,a%b);
联立方程 ax + by = (a%b)*y` + bx`;
ax + by = (a - a/b*b) * y` + bx`;
ax + by = ay` - a/b*b * y` + bx`;
ax + by = ay` + b(x`- a/b * y`);
对应项的 x = y`,y = (x` - a/b * y`);
令A = b,B = a%b; Ax`` + By`` = gcd(A,B);
由此不断递推,直到B = 0;则Ax = gcd(A,0) = A;
x`` = 1;y``为任意值,这里我们赋为0;
则可根据x = y`,y = (x` - a/b * y`),得到上层解从而解得方程
#include <iostream> #include <cstdio> using namespace std; 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);// d 表示 a,b的gcd; 现在的y = x`,x = y`; y -= a/b*x; return d; } 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 a,n; while(cin>>a>>n){ cout << mod_reverse(a,n) << endl; } return 0; }