Files
python/TangDou/LuoGuBook/P1593_ExGcd.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

52 lines
2.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
/**前导知识:
裴蜀定理: 对于任意正整数a,b,一定存在非零整数x,y,使得ax+by=gcd(a,b)
证明:因为 gcd(a,b)|a,同时gcd(a,b)|b,就是说a是gcd(a,b)的倍数,b也是gcd(a,b)的倍数,所以a+b也一定是gcd(a,b)的倍数。
假如我们找到这个最小的倍数是1,那么就是ax+by=gcd(a,b)
*/
/**
* 功能:扩展欧几里德算法模板
* @param a 第一个数字
* @param b 第二个数字
* @param x a的系数,按地址传入,因为最终要一并返回这个值x
* @param y b的系数,按地址传入,因为最终要一并返回这个值x
* @return a,b的最大公约数
*/
int exgcd(int a, int b, int &x, int &y) {
if (!b) { //如果b==0
x = 1, y = 0; //a与0的最大公约数肯定是0,所以给出一个最小解即可,比如x=1,y=0。
return a;
}
//如果b!=0
int d = exgcd(b, a % b, y, x);//d是最大公约数,这里a和b颠倒了,所以系数也需要翻转一下
//下面的是重点,在变换过程中,系数会发生变化:
/**
1、现在 by+(a%b)x=gcd(a,b)
2、a % b=a- ⌊a/b⌋ * b 这个是定义,就是把 a里面的b的整数倍都减出去,剩下的就是余数。⌊a/b⌋ 下取整的意思。
3、将 2式代入1式,就是
by+(a- ⌊a/b⌋ * b)x = gcd(a,b)
b(y-⌊a/b⌋*x)+a*x=gcd(a,b)
也就是说:a的系数x没有变化,b的系数变化为 y-⌊a/b⌋*x ,也就是 y=y-a/b *x,再简写一下: y-= a/b *x
*/
y -= a / b * x;
return d;
}
//利用扩展欧几里德求逆元
int inv(int a, int b) {
int x, y;
int gcd = exgcd(a, b, x, y);
//m与n不互质,乘法逆元不存在
if (1 != gcd) return -1;
else return (x + b) % b; //为了使余数一定为正数,模运算系统的特性
}
int main() {
cout << inv(13, 10) << endl;
return 0;
}