Ps:很久以前学的,一直以来都是套模板,感觉忘得差不多了,所以复习一下- -
欧几里得算法
作用:
计算两个数的最大公约数。
算法:
欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。
用gcd(a, b)表示a和b的最大公约数。
gcd函数的基本性质:gcd(a,b)=gcd(b,a)=gcd(-a,b)=gcd(|a|,|b|)=gcd(a,b-a)
C实现:
1 typedef long long int64; 2 3 int64 gcd(int64 a, int64 b) 4 { 5 return b == 0 ? a : gcd(b, a% b); 6 }
扩展欧几里得算法
作用:
计算两个数a, b的最大公约数的同时,求出两个整数x, y使得a*x + b*y = gcd(a, b),且|x| + |y|取得最小值。
算法:
用以下过程进行模拟:
用类似辗转相除法,求二元一次不定方程47x+30y=1的整数解。
- 47=30*1+17
- 30=17*1+13
- 17=13*1+4
- 13=4*3+1
然后把它们改写成“余数等于”的形式
- 17=47*1+30*(-1) //式1
- 13=30*1+17*(-1) //式2
- 4=17*1+13*(-1) //式3
- 1=13*1+4*(-3)
然后把它们“倒回去”
- 1=13*1+4*(-3) //应用式3
- 1=13*1+[17*1+13*(-1)]*(-3)
- 1=13*4+17*(-3) //应用式2
- 1=[30*1+17*(-1)]*4+17*(-3)
- 1=30*4+17*(-7) //应用式1
- 1=30*4+[47*1+30*(-1)]*(-7)
- 1=30*11+47*(-7)
得解x=-7, y=11
C实现:
1 typedef long long int64; 2 3 void ext_gcd(int64 a, int64 b, int64& d, int64& x, int64& y) 4 { 5 if (!b) d = a, x = 1, y = 0; 6 else{ 7 ext_gcd (b, a%b, d, y, x); 8 y -= x * (a / b); 9 } 10 }