線性同余方程
阿新 • • 發佈:2018-04-22
turn lcm 線性 out 如何 算法 我們 怎麽 exgcd
如何解方程a*x≡b(mod m)呢?因為a*x-b|m, 故令a*x-b=-y*m,即a*x+m*y=b。根據Bezout定理,該方程有解當且僅當gcd(a,m)|b。我們把等式兩邊同乘以gcd(a,m)/b,得到a*x0+m*y0=gcd(a, m)。這個方程可以用擴展歐幾裏得算法求得得到x0。等式是怎麽乘的,就再把它除回來,也就是x=x0*b/gcd(a,m)。關於方程的通解,a*x+k*lcm(a,m)+m*y-k*lcm(a,m)=b,lcm(a,m)=a*m/gcd(a,m),也就是a*(x+k*m/gcd(a,m))+m*(y+k*a/gcd(a,m))=b,所以方程的通解為所有與x同余m/gcd(a,m)的數。若要求最小正整數解,令p=m/gcd(a,m),然後x=(x%p+p)%p即可。
ll Exgcd(ll a, ll b, ll &x, ll &y) { if (b == 0) { x = 1; y = 0; return a; } ll d = Exgcd(b, a%b, x, y); ll tx = x; x = y; y = tx - (a / b) * y; return d; } ll Gcd(ll a, ll b) { return b ? Gcd(b, a%b) : a; } ll Eq(ll a, ll b, ll m) { ll gcd = Gcd(a, m); if (b%gcd) return -1; ll x, y; Exgcd(a, m, x, y); x = x * b / gcd; ll p = m / gcd; return (x%p+p) % p; }
線性同余方程