欧几里得算法gcd及其拓展exgcd和线性同余方程

欧几里得算法gcd

其实就是初中学的辗转相除法,如果有同学想了解为什么辗转相除法能求出最大公约数,我可以推荐一个链接

int gcd(int a, int b) {
	return b == 0 ? a : gcd(b, a % b);
}

最小公倍数lcm=a*b/gcd(a,b)
在stl库里面也有gcd,只需要调用algorithm中的__gcd(),注意的是两个下划线

欧几里得算法exgcd

用于解决如下问题:
已知a,b,求解一组x,y,使其满足 ax + by = gcd(a, b) (该等式称贝祖等式)
另有结论:
设a, b, c为任意整数,g = gcd(a, b), 方程ax + by = g的一组解为(x0, y0)
当c是g的倍数时,方程ax + by = c的一组解为(x0 * c / g, y0 * c / g);
当c不是g的倍数时无整数解
设a, b, c为任意整数,g = gcd(a, b), 方程ax + by = c的一组解为(x0, y0)
则它的任意解都可以写成(x0 + kb’,y0-ka’), 其中a’ = a / gcd(a,b) , b’ = b / gcd(a, b)

//函数返回为a,b的最大公约数,求得的解存放在x,y中
int exgcd(int a, int b, int& x, int& y)
{
	if (b == 0)
	{
		x = 1;
		y = 0;
		return a;
	}
	else
	{
		int g = exgcd(b, a % b, x, y);
		int x2 = x;
		int y2 = y;
		x = y2;
		y = x2 - a / b * y2;
		return g;
	}
}

线性同余方程

a*x≡b(mod c)
百度讲解:数论中,线性同余方程是最基本的同余方程,“线性”表示方程的未知数次数是一次.
其原理只是欧几里得算法拓展exgcd的模情况mod,原理差不多

int ex_gcd(int a, int b, int& x, int& y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  int d = ex_gcd(b, a % b, x, y);
  int temp = x;
  x = y;
  y = temp - a / b * y;
  return d;
}
bool liEu(int a, int b, int c, int& x, int& y) {
  int d = ex_gcd(a, b, x, y);
  if (c % d != 0) return 0;
  int k = c / d;
  x *= k;
  y *= k;
  return 1;
}

你可能感兴趣的:(数学)