#include 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; }