扩展欧几里得算法
- 裴蜀定理:对于任意正整数 a 、 b a、b a、b ,一定存在非零整数 x 、 y x、y x、y ,使得 a x + b y = ( a , b ) ax + by = (a, b) ax+by=(a,b) (最大公约数)
1.AcWing877.扩展欧几里得算法
#include<iostream>
using namespace std;
// (a, b) = (b, a mod b)
// return b ? gcd(b, a % b) : a;
int gcd(int a, int b) {
if (!b) return a;
return gcd(b, a % b);
}
// ax + by = (a, b)
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() {
int m;
scanf("%d", &m);
while (m--) {
int a, b, x, y;
scanf("%d%d", &a, &b);
exgcd(a, b, x, y);
printf("%d %d\n", x, y);
}
return 0;
}
2.AcWing878.线性同余方程
- 给定 a 、 m 、 b a、m、b a、m、b,求一个整数 x x x 使得 a x ≡ b ( m o d m ) ax~≡b~(mod~m) ax ≡b (mod m)
#include<iostream>
using namespace std;
// (a, b) = (b, a mod b)
// return b ? gcd(b, a % b) : a;
int gcd(int a, int b) {
if (!b) return a;
return gcd(b, a % b);
}
// ax + by = (a, b)
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() {
int m;
scanf("%d", &m);
while (m--) {
int a, b, m;
scanf("%d%d%d", &a, &b, &m);
int x, y;
int d = exgcd(a, m, x, y);
if (b % d) puts("impossible");
else printf("%d\n", (long long)x * (b / d) % m);
}
return 0;
}
tips:文章内容参考acwing算法刷题课程,题解图示内容及代码根据老师课程、以及自己对知识的理解,进行二次整理和部分补充,仅供学习参考使用,不可商业化。