【数论】扩展欧几里得
$给定n对于正整数a,b,求出一组x,y,使其满足a \times x + b \times y = gcd(a,b)$
首先给出Bezout定理:
在数论中,裴蜀定理是一个关于最大公约数的定理,说明对任何整数a,b和d,关于未知数x和y的线性方程:ax + by = m,有整数解时当且仅当m是a及b的最大公约数d的倍数。裴蜀等式有解时必然有无穷多个整数解,每组x,y都称为裴蜀数,可用扩展欧几里得算法求得。
$已知gcd(a,b) = gcd(b,a \% b),即ax + by = bx + a \% b \times y =d;$
$当b =0,ax+0=d,x = 1,y = 0;$
$当b \neq 0,$
$bx^{'} + (a - \left \lfloor \frac{a}{b} \right \rfloor b)y^{'} = d;$
$ay^{'} + b(x^{'} - \left \lfloor \frac{a}{b} \right \rfloor y^{'}) = d;$
$x = y^{'},y = x^{'} - \left \lfloor \frac{a}{b} \right \rfloor y^{'};$
1 #include <iostream> 2 using namespace std; 3 int gcd(int a,int b,int& x,int& y) 4 { 5 if(!b) 6 { 7 x = 1; 8 y = 0; 9 return a; 10 } 11 else 12 { 13 int d = gcd(b,a%b,x,y); 14 int tmp = x; 15 x = y; 16 y = tmp - a/b*y; 17 return d; 18 } 19 } 20 21 int main() 22 { 23 int n; 24 cin >> n; 25 while(n--) 26 { 27 int a,b,x,y; 28 cin >> a >> b; 29 gcd(a,b,x,y); 30 cout << x << " " << y << endl; 31 } 32 return 0; 33 }
线性同余方程:
$给定a,b,m,对于每组数求出一个x,使其满足a \times x \equiv b(mod m),如果误解则输出 impossible$
$对于a \times x \equiv b(mod m),\exists y \in Z,ST \quad ax = ym+b;$
$即ax-my=b,根据裴蜀定理,b必须得是d的倍数才可能有整数解,即b = kd;$
$令x' = x/k,y'=-y/k,可得ax'+my'=d,因此使用扩展欧几里得算法求解出x',再扩大k=\frac{b}{d} 倍即可。$
1 #include <iostream> 2 using namespace std; 3 4 int exgcd(int a,int b,int& x,int& y) 5 { 6 if(!b) 7 { 8 x = 1; 9 y = 0; 10 return a; 11 } 12 else 13 { 14 int d = exgcd(b,a%b,y,x); 15 y = y - a/b*x; 16 return d; 17 } 18 } 19 20 int main() 21 { 22 int n; 23 cin >> n; 24 while(n--) 25 { 26 int a,b,m,x,y; 27 cin >> a >> b >> m; 28 int d = exgcd(a,m,x,y); 29 if(b % d) 30 cout << "impossible" << endl; 31 else 32 cout << (long long)x * b / d % m << endl; 33 } 34 return 0; 35 }

浙公网安备 33010602011771号