1)求解線性不定方程
ax + by = c
先求出一組解, 然后考慮如何表示通解, 設d = gcd(a, b), 假設c不是d的倍數, 則左邊是d的倍數而右邊不是, 則方程無解, 所以方程有解當且僅當d | c.
設c = c' * d, 我們先考慮方程 ax + by = d, 這樣由擴展gcd便可求出一組解 (x', y'), 則(c'x', c'y')就是原方程的一組解,然后考慮通解:
假設有兩組解(x1, y2) , (x2, y2), 有 ax1 + by1 == ax2 + by2 = c, 移項得: a(x1 - x2) == b(y2 - y1), 消去d后有 a'(x1 - x2) == b'(y2 - y1),
此時a' 和 b' 互素, 所以(x1 - x2)一定是b'的倍數, 而(y2 - y1)一定是a'的倍數, 由此可得到通解:
給一組特解(x, y), 通解為(x - kb', y + ka').
2)求解模線性方程
ax = b(mod n)
其實方程等價於 ax - ny = b, 標准模線性方程,但是得考慮剩余系。
算法導論上有兩個定理:
定理一:設d = gcd(a, n), 假定對整數x', y', 有d = ax' + ny', 如果d | b, 則方程ax = b(mod)有一個解的值為x0, 滿足:、
x0 = x'(b / d)(mod n)
定理二:假設方程ax = b(mod n)有解, x0是方程的任意一個解, 則方程對模n恰有d個不同的解, 分別為: xi = x0 + i * (n / d), 其中 i = 1,2,3......d - 1
有了這兩個定理, 解方程就不難了。
View Code
1 void linear_mod_equation (int a, int b, int n, int *sol) 2 { 3 int d, x, y; 4 gcd (a, n, d, x, y ); 5 if (b % d) d = 0; 6 else 7 { 8 sol [0] = x * ( b / d ) % n ; 9 for (int i = 1; i < d; ++i) 10 sol[i] = (sol[i - 1] + n / d) % n ; 11 } 12 }
如果gcd(a, n) == 1, 則方程有唯一解, 即解為a的逆。
View Code
1 ll inv(ll a, ll n) 2 { 3 ll d, x, y; 4 gcd(a, n, d, x, y); 5 return d == 1 ? (x % n + n) % n : -1; 6 }
