exgcd

题目传送门

对于不等式: a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b),给定 a , b a,b a,b,求出符合条件的一组 x , y x,y x,y

推导: (假定a>=b)

  1. a x 1 + b y 1 = g c d ( a , b ) ax_1+by_1=gcd(a,b) ax1+by1=gcd(a,b)
  2. b x 2 + a % b y 2 = g c d ( b , a % b ) bx_2+a\%by_2=gcd(b,a\%b) bx2+a%by2=gcd(b,a%b)
  3. g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a\%b) gcd(a,b)=gcd(b,a%b)
  4. a x 1 + b y 1 = b x 2 + a % b y 2 ax_1+by_1=bx_2+a\%by_2 ax1+by1=bx2+a%by2
  5. a % b = a − ⌊ a b ⌋ × b a\%b=a-\lfloor\frac{a}{b}\rfloor\times b a%b=aba×b
  6. a x 1 + b y 1 = b x 2 + ( a − ⌊ a b ⌋ × b ) y 2 ax_1+by_1=bx_2+(a-\lfloor\frac{a}{b}\rfloor\times b)y_2 ax1+by1=bx2+(aba×b)y2
  7. a x 1 + b y 1 = a y 2 + b x 2 − ⌊ a b ⌋ × b y 2 ax_1+by_1=ay_2+bx_2-\lfloor\frac{a}{b}\rfloor\times by_2 ax1+by1=ay2+bx2ba×by2
  8. a x 1 + b y 1 = a y 2 + b ( x 2 − ⌊ a b ⌋ × y 2 ) ax_1+by_1=ay_2+b(x_2-\lfloor\frac{a}{b}\rfloor\times y_2) ax1+by1=ay2+b(x2ba×y2)
  9. x 1 = y 2 , y 1 = x 2 − ⌊ a b ⌋ × y 2 x_1=y_2,y_1=x_2-\lfloor\frac{a}{b}\rfloor\times y_2 x1=y2,y1=x2ba×y2

向下迭代,直到 b = 0 b=0 b=0,此时将 x = 1 , y = 0 x=1,y=0 x=1y=0返回,向上迭代,即可得到 x 1 , y 1 x_1,y_1 x1,y1

通解: 我们刚才求的只是 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)的一组特解,但是题目往往让我们求最小整数解。通过求x的最小整数解为例,假设存在另外的一组解 x 0 , y 0 x_0,y_0 x0,y0

  1. a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)
  2. y = g c d ( a , b ) − a x b y=\frac{gcd(a,b)-ax}{b} y=bgcd(a,b)ax
  3. y 0 = g c d ( a , b ) − a x 0 b y_0=\frac{gcd(a,b)-ax_0}{b} y0=bgcd(a,b)ax0
  4. 假设 x 0 = x + i x_0=x+i x0=x+i
  5. y 0 = g c d ( a , b ) − a x b − a i b y_0=\frac{gcd(a,b)-ax}{b}-\frac{ai}{b} y0=bgcd(a,b)axbai
  6. y 0 = y − a i b y_0=y-\frac{ai}{b} y0=ybai
  7. 因为 y ∈ Z , y 0 ∈ Z y∈Z,y_0∈Z yZ,y0Z
  8. a ∗ i / b ∈ Z a*i/b∈Z ai/bZ
  9. a / b ∗ i ∈ Z a/b*i∈Z a/biZ
  10. a , b a,b a,b互质,则 i m i n = b i_{min}=b imin=b
  11. a , b a,b a,b不互质,那么存在 a ′ / b ′ ∗ i ∈ Z a'/b'*i∈Z a/biZ
  12. a ′ = a / g c d ( a , b ) , b ′ = b / g c d ( a , b ) a'=a/gcd(a,b),b'=b/gcd(a,b) a=a/gcd(a,b),b=b/gcd(a,b)

由此,可知 x i = x + k ∗ i , i = b ′ = b / g c d ( a , b ) x_i=x+k*i,i=b'=b/gcd(a,b) xi=x+ki,i=b=b/gcd(a,b)
同理可知, y i = y + k ∗ j , j = a ′ = a / g c d ( a , b ) y_i=y+k*j,j=a'=a/gcd(a,b) yi=y+kj,j=a=a/gcd(a,b)

代码(递归版):

void exgcd(int a,int b,int &x,int &y)
{
	if(!b)
	{
		x = 1;
		y = 0;
		return ;
	}
	exgcd(b,a%b,x,y);
	int t = x;
	x = y;
	y = t - (a / b) * y;
	return ;
}

代码(非递归版):

void exgcd(int a,int b,int &x,int &y)
{
	x = 1, y = 0;
	int x1 = 0, y1 = 1, a1 = a, b1 = b;
	while (b1)
	{
		int q = a1 / b1;
		tie(x, x1) = make_tuple(x1, x - q * x1);
		tie(y, y1) = make_tuple(y1, y - q * y1);
		tie(a1, b1) = make_tuple(b1, a1 - q * b1);
	}
	return ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值