中國剩餘定理(個人筆記)
前序
已知a和x0,且x % a ≡ x0, 則x = (x0 % a + a) % a
1. 擴充套件歐幾里德演算法
求出a與b的最大公因數d的同時,還能解出ax+by=gcd(a,b)中(x,y)的一組特解
int exgcd(int a, int b, int &x, int &y){
if(b == 0) {x = 1, y = 0; return a; }
int d = exgcd(b, a % b, x, y);
int tmp = x;
x = y, y = tmp - a / b * y;
return d;
}
這裡如果將x與y交換去呼叫exgcd函式,就可以得到以下程式碼
int exgcd(int a, int b, int &x, int &y){
if(b == 0) { x = 1, y = 0; return a; }
int d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
解得的x和y為它們的一組特解(x0, y0),它們的通解為x = x0 + b / gcd(a,b), y = y0 - a / gcd(a,b)
2.同餘方程
給出a,b和m,求滿足a ∗ x ≡ b (mod m)的x,且x為最小正整數解
變形 => a * x = k * m + b, 即 a * x - k * m = b
只要滿足b % gcd(a, m) == 0, 那麼就一定存在解x
直接帶入exgcd函式即可求出一組特解(x0, k0)滿足a * x - k * m = gcd(a, m),所以x1 = x0 * b / gcd(a, m)的值就滿足a * x - k * m = b
為了得到最小正整數解,只需令x2 = (x1 % m + m) % m,那麼x2就是最終的結果
3.中國剩餘定理
給出n組式子x ≡ mi (mod ai)中的mi,ai,求出一個最小正整數x滿足這n組式子
取其中兩個式子,可以得到
x = k1 * a1 + m1
x = k2 * a2 + m2
**那麼整理得到 **
a1 * k1 - a2 * k2 = m2 - m1
(此時需要判斷是否存在解!!!也就是說,(m2 - m1) % gcd(a1, a2) == 0必須成立才能有解)
*這樣,通過呼叫exgcd函式就可以得到一個特解k1 = (m2 - m1) / gcd(a1, a2),通解為k1 + k * a2 / gcd(a1, a2), 同理k2的通解為 k2 + k * a1 / gcd(a1,a2)(因為上邊的式子為減號,所以這裡的兩個通解全為加k倍,而不是一加一減),那麼
t = a2 / gcd(a1, a2)
x = [k1 + k * t] * a1 + m1
= a1 * t * k + a1 * k1 + m1
為了讓x變得更小,這裡我們可以讓k1 + k * t = (k1 % t + t) % t
此時我們可以將a1 * t當作新的a,將a1 * k1 + m1當作新的m,即m1 = a1 * k1 + m1, a1 = a1 * t,也滿足x = k1 * a1 + m1的格式,就將x = k1 * a1 + m1 和 x = k2 * a2 + m2合併成了一個式子
同理,最後可以將n個式子合併成一個式子,只剩下更改後的a1和m1,那麼答案x = (m1 % a1 + a1) % a1
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
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, y, x);
y -= a / b * x;
return d;
}
int main(void)
{
bool flag = true;
int n; cin >> n;
ll a1, m1; cin >> a1 >> m1;
for (int i = 1; i < n; ++i) {
ll a2, m2; cin >> a2 >> m2;
ll k1, k2;
ll d = exgcd(a1, -a2, k1, k2);
if ((m2 - m1) % d != 0) { flag = false; break; }
k1 *= (m2 - m1) / d;
ll t = a2 / d;
k1 = (k1 % t + t) % t;
m1 = a1 * k1 + m1;
a1 = abs(a1 * t);
}
if (flag) cout << (m1 % a1 + a1) % a1 << endl;
else cout << "-1\n";
return 0;
}
END
相關文章
- 中國剩餘定理
- 擴充套件中國剩餘定理(EXCRT)學習筆記套件筆記
- 中國剩餘定理詳解
- 中國剩餘定理(構造)
- 擴充套件中國剩餘定理套件
- 擴充套件中國剩餘定理詳解套件
- Strange Way to Express Integers(中國剩餘定理+不互質)Express
- 用中國剩餘定理解 POJ1006
- 數論入門基礎(同餘定理/費馬小定理/擴充套件歐幾里德演算法/中國剩餘定理)套件演算法
- HDU1788Chinese remainder theorem again(中國剩餘定理 簡單)REMAI
- X問題(中國剩餘定理+不互質版應用)hdu1573
- Bell(hdu4767+矩陣+中國剩餘定理+bell數+Stirling數+歐幾里德)矩陣
- 二次剩餘Cipolla演算法學習筆記演算法筆記
- 獲取波場(Tron)錢包TRX、USDT餘額和剩餘頻寬、能量 - 筆記筆記
- JavaScript 剩餘運算子JavaScript
- 留數定理筆記筆記
- 獲取linux可用記憶體 剩餘記憶體Linux記憶體
- ES6語法學習筆記之箭頭函式、剩餘引數筆記函式
- 泛函分析筆記(十四)Baire定理,Banach-Steinhaus定理泛函分析筆記AI
- 個人筆記筆記
- 筆記本Win10系統如何開啟電池剩餘時間指示器筆記Win10
- boot分割槽剩餘空間不足boot
- parted掛載硬碟剩餘空間硬碟
- hdu 1792 A New Change Problem 剩餘系
- 個人筆記-vuex筆記Vue
- linux檢視剩餘磁碟空間Linux
- Codeforces 687B. Remainders Game[剩餘]REMAIGAM
- 文字相似度計算之餘弦定理
- 前端安全——個人筆記前端筆記
- ruby ,rake個人筆記筆記
- ES6 - 函式與剩餘運算子函式
- 學習筆記:Burnside引理、Pólya定理筆記IDE
- 【讀書筆記】餘華 - 活著筆記
- 大宇擬出售北軟剩餘股份及《仙劍》IP
- 檢視Win10啟用剩餘時間Win10
- JS複習個人筆記JS筆記
- 【筆記】組合恆等式和二項式定理筆記恆等式
- 如何檢視linux系統中空閒記憶體/實體記憶體使用/剩餘記憶體Linux記憶體