【扩展欧几里德】模版及原理

题目描述

求ax+by=gcd(a,b) x最小的正整数解。

输入

a b

输出

a,b最大公约数 x y,x>0且最小

样例输入

154 60

样例输出

2 23 -59
 
原理:
gcd(a,b)=x0a+y0b
gcd(b,a%b)=x1b+y1(a%b)=x1b+y1(a-a/b*b)
因为                gcd(a,b)=gcd(b,a%b)
得                   x0a+y0b=x1b+y1(a-a/b*b)
合并得             x0a+y0b=y1a+(x1-a/b*y1)b
根据恒等定理: x0=y1 y0=x1-a/b*y1
 

对于不定整数方程pa+qb=c,若 c mod Gcd(p, q)=0,则该方程存在整数解,否则不存在整数解。
上面已经列出找一个整数解的方法,在找到p * a+q * b = Gcd(a,b)的一组解p0,q0后,p * a+q * b = Gcd(a,b)
的其他整数解满足:
 p = p0 + b/Gcd(a,b) * t
 q = q0 ­ a/Gcd(a,b) * t(其中t为任意整数)
 至于pa+qb=c的整数解,只需将p * a+q * b = Gcd(a,b)的每个解乘上 c/Gcd(a,b) 即可。

 

所以解的最小段为b/gcd(a,b) x的最小值即为取模后的答案.

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int exgcd(int a,int b,int &x,int &y)
 7 {
 8     if(!b)
 9     {
10         x=1;y=0;
11         return a;
12     }
13     int r=exgcd(b,a%b,x,y);
14     int t=x;
15     x=y;
16     y=t-a/b*y;
17     return r;
18 }
19 int main()
20 {
21     int a,b,x,y;
22     scanf("%d%d",&a,&b);
23     int p=exgcd(a,b,x,y);
24     int t=b/p;
25     x=(x%t+t)%t;
26     y=(p-(long long)x*a)/b;
27     printf("%d %d %d",p,x,y);
28     return 0;
29 }

 

posted @ 2017-06-16 11:41 PIPIBoss 阅读(...) 评论(...) 编辑 收藏