You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

52 lines
2.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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