【扩展欧几里德】模版及原理
题目描述
求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 }