拓展欧几里得
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <vector> 5 6 using namespace std; 7 8 #define ll long long 9 10 const int INF = 1e9; 11 const ll MOD = 19940417; 12 13 //裴蜀定理:若 ax + by = n 有解,则 gcd(a, b) | n 14 //拓展欧几里得:求 ax + by = gcd(a, b) 的解,通过辗转相除法得到一组特解:x0 y0 15 // 得到 ax + by = c 的特解: 16 // x = x0 * c / gcd(a, b) 17 // y = y0 * c / gcd(a, b) 18 // 通解: 19 // X = x + b / gcd(a, b) * t 20 // Y = y - a / gcd(a, b) * t (t = 0, 1, 2, 3 ...) 21 //最小非零解: x = (x % b + b) % b 22 // ax + by = gcd(a, b) 23 // ax + by + k * ab - k * ak = gcd(a, b) 24 // a(x + kb) + b(y - bk) = gcd(a, b) ----> x = (x % b + b) % b 25 26 ll exgcd(ll a, ll b, ll &x, ll &y) 27 { 28 29 if(b == 0){//推理1,终止条件 30 x = 1; 31 y = 0; 32 return a; 33 } 34 ll r = exgcd(b, a%b, x, y); 35 //先得到更底层的x2,y2,再根据计算好的x2,y2计算x1,y1。 36 //推理2,递推关系 37 ll t = y; 38 y = x - (a/b) * y; 39 x = t; 40 return r; 41 } 42 43 void solve() 44 { 45 46 //ax同余1(mod prime) 求最小正整数解 47 // ax + by = n ---> ax' + by' = gcd(a, b) 48 // k = gcd(a, b) k*(ax' + by') = n 49 //以下 a, b, x, y对应上面 a, b, x', y' 50 ll a, b, x, y; 51 //以下求出mod不为质数的逆元 52 // a / b % mod c 53 // a / b * b^-1 ≡ x * b^-1(mod c) 54 // b * b^-1 ≡ 1 (mod c) 55 // b * b^-1 + y * c = 1 56 // a * x + b * y = 1 57 exgcd(2, MOD, x, y); 58 ll inv2 = x; 59 exgcd(6, MOD, x, y); 60 ll inv6 = x; 61 62 cout << "inv2 = " << (inv2 + MOD) % MOD << endl; 63 64 cout << "inv6 = " << (inv6 + MOD) % MOD << endl; 65 } 66 67 int main() 68 { 69 70 solve(); 71 72 return 0; 73 }
1