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 Permalink 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;
}