扩展欧几里得
设最大公约数为 d,
裴蜀定理:对于任意正整数 a, b,一定存在非零整数 x, y,使得 (ax : + : by : = : d) 。
递归过程中,
(ecause) (by : + :(a : - : lfloor frac{a}{b} floor : cdot : b) : x : = : d)
( herefore) (ax : + (y : - : lfloor frac{a}{b} floor : cdot : x) : b : = : d)
时间复杂度:O((log)n)
#include <bits/stdc++.h>
using namespace std;
const char nl = '
';
int exgcd(int a, int b, int &x, int &y){
if (!b){
x = 1, y = 0;
return a;
}
int d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
int main(){
ios::sync_with_stdio(false);
// cin.tie(nullptr);
int a, b;
while (cin >> a >> b){
int x = 0, y = 0;
exgcd(a, b, x, y);
cout << x << " " << y << nl;
}
return 0;
}
线性同余方程
时间复杂度:O((log)n)
https://www.luogu.com.cn/problem/P1082
题意:求关于 x 的同余方程 (a x equiv 1 pmod {b}) 的最小正整数解。
#include <bits/stdc++.h>
using namespace std;
const char nl = '
';
int exgcd(int a, int b, int &x, int &y){
if (!b){
x = 1, y = 0;
return a;
}
int d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
int main(){
ios::sync_with_stdio(false);
// cin.tie(nullptr);
int a, b;
while (cin >> a >> b){
int x, y;
exgcd(a, b, x, y);
cout << (x + b) % b << nl;
}
return 0;
}