洛谷 P1082 同余方程(同余exgcd)
生活随笔
收集整理的這篇文章主要介紹了
洛谷 P1082 同余方程(同余exgcd)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
嗯...
?
題目鏈接:https://www.luogu.org/problem/P1082
?
這道題很明顯涉及到了同余和exgcd的問題,下面推導一下:
首先證明有解情況:
ax + by = m有解的必要條件是 m mod gcd(a, b) = 0
a為gcd(a, b)的倍數,b為gcd(a, b)的倍數,x、y為整數,
所以ax + by是gcd(a, b)的倍數,所以m是gcd(a, b)的倍數
然后證明a、b互質(下面會用到):
本題中1 mod gcd(a, b) = 0,所以gcd(a, b)? = 1,所以a、b互質
同余:
a≡b(mod n) --> 含義:a和b關于模n同余,即 a mod n = b mod n。
所以不難推出,a≡b的充要條件是a-b是n的整數倍(a > b)。
因為a-b是n的整數倍,所以a-b = ny(y為倍數)
所以,根據同余,我們可以把本題中的同余式轉化為(注:這里的a.b與上文不同):
ax≡1(modb)? --> ax % b = 1 % b --> ax?- 1 = by --> ax - by = 1
下一步,便進行exgcd(關于exgcd的證明見:https://www.luogu.org/problemnew/solution/P1082),分別求出ax - by = 1中x和y的值。
最后進行答案處理:
因為答案要求是x的最小正整數,所以我們進行一個答案處理:x = (x % b + b) % b
證明其正確性:
設新得到的x為xn,x = kb + q(q < b)則:
x % b = q ,把x % b = q帶入 xn =?(x % b + b) % b,得
xn =?(x % b + b) % b =?(q + b) % b = (q % b + b % b) % b = q % b = q
?把xn = q帶入x = kb + q,得,x = kb + xn, 所以xn = x - kb,然后再根據下面的推導得知它是正確的...
證明:
x批量地減去或加上?b,能保證?ax + by = ax?+?by?=?1:
ax + by =?1
ax + by + k*ba - k*ba?=?1
a (x + kb) + (y - ka) b = 1
1.顯然這并不會把方程中任何整數變成非整數。
2.“加上或減去?b”不會使?x?錯過任何解。可以這么理解:
已經求出一組整數?x,y?使得?ax+by?=1 ,也就是(1 - ax) / b = y。y?是整數,可見目前?1?ax?是?b?的倍數。現在想改變?x并使得方程仍然成立。
已知?a,b?互質,假若x的變化量Δx不是b的倍數,則1?ax?的變化量?a*Δx也不是?bb?的倍數,這會使得1-ax不再是b的倍數,則y不是整數了。
僅當x的變化量是b的倍數時,1?ax能保持自己是b的倍數,此時就出現新的解了。
?
AC代碼:
?
1 #include<cstdio> 2 #include<iostream> 3 4 using namespace std; 5 //ax % b == 1 % b --> ax - 1 = y * b --> ax - yb == 1 6 7 long long d, x, y; 8 9 inline void exgcd(long long a, long long b, long long &d, long long &x, long long &y){ 10 if(!b) {d = a; x = 1; y = 0;} 11 else{ exgcd(b, a % b, d, y, x); y -= x * (a / b);} 12 } 13 int main(){ 14 long long a,b; 15 scanf("%lld%lld", &a, &b); 16 exgcd(a, b, d, x, y); 17 x = (x % b + b) % b; 18 printf("%lld", x); 19 return 0; 20 } AC代碼?
轉載于:https://www.cnblogs.com/New-ljx/p/11261791.html
總結
以上是生活随笔為你收集整理的洛谷 P1082 同余方程(同余exgcd)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构学习笔记1
- 下一篇: BZOJ1030: [JSOI2007]