【luogu P1082 同余方程】題解
阿新 • • 發佈:2018-02-26
ont 當前 int 關於 學習 並且 div iostream color
最近一直在學習數論,講得很快,害怕落實的不好,所以做一道luogu的同余方程練練手。
關於x的同余方程
ax ≡ 1 mod m
那麽x其實就是求a關於m的乘法逆元
ax + my = 1
對於這個不定方程的全部解是
{ x = x0 + m/gcd(a,m)
{ y = y0 - a/gcd(a,m)
我們可以用exgcd來求出其中的一組特解x0
那麽什麽是exgcd?
先不考慮exgcd,假設當前我們要處理的是求出 a 和 b的最大公約數,並求出 x 和 y 使得 a*x + b*y= gcd ,而我們已經求出了下一個狀態:b 和 a%b 的最大公約數,並且求出了一組x1 和y1 使
得: b*x1 + (a%b)*y1 = gcd
那麽我們看 a%b = (a-(a/b)*b)
所以
gcd = b*x1 + (a%b)*y1
= b*x1 + (a-(a/b)*b)*y1
= b*x1 + a*y1 – (a/b)*b*y1
= a*y1 + b*(x1 – a/b*y1)
那麽我們對比前面一組 a*x + b*y = gcd
在這裏 x = y1
y = x1 - a/b*y1
所以我們就可以遞歸來求exgcd了。
在gcd當中,gcd(a,b) = gcd(b,a%b)
那麽exgcd的代碼其實也多不了多少
1 #include <cstdio> 2 #include <algorithm> 3#include <iostream> 4 #define ll long long 5 using namespace std; 6 ll a, b, x, y, k, ans; 7 int exgcd(ll a, ll b) 8 { 9 if(b == 0) 10 { 11 x = 1; y = 0; 12 return a; 13 } 14 exgcd(b,a%b); 15 k = x; 16 x = y; 17 y = k - a/b * y; 18 return x;19 } 20 int main() 21 { 22 cin>>a>>b; 23 ans = exgcd(a,b); 24 cout<<(ans+b)%b; 25 return 0; 26 }
其實你看gcd的代碼這麽短,肯定是背過的吧(#滑稽),exgcd也長不了多少,不行就背過吧(逃
【luogu P1082 同余方程】題解