ecgcd(解二元不定方程)
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=775
关于扩展欧几里得算法还是推一遍好啦;
有方程:a*x+b*y=d=gcd(a, b) --- 1式(只要a, b不全为0则此方程必有解,不过我不会证明,望大神路过时教一下);
又有gcd(a, b)=gcd(b, a%b); --- 2 式 (证明: http://www.cnblogs.com/geloutingyu/p/6209026.html)
将2式代入1式中得到:b*x1+(a%b)*y1=b*x1+(a-a/b*b)*y1=a*y1+b*(x1-a/b*y1);----3式
比较1式和3式,由恒等式定理可得:x=y1; y=x1-(a/b)*y1; 即上一层递归式中的y就是本层递归式中的x,上一层递归式中的y就是 x1-(a/b)*y1;
代码:
1 #include <bits/stdc++.h>
2 #define ll long long
3 using namespace std;
4
5 int x, y;
6
7 void exgcd(int a, int b)
8 {
9 if(!b) //***b==0结束递归条件
10 {
11 x=1;
12 y=0;
13 return;
14 }
15 exgcd(b, a%b);
16 int t=x;
17 x=y;
18 y=t-(a/b)*y;
19 }
20
21
22 int main(void)
23 {
24 int a, b, d;
25 while(~scanf("%d%d", &a, &b)) //××本题中这里用cin 会超时,即便加了输入外挂也一样,并不懂why;
26 {
27 exgcd(a, b);
28 printf("%d %d\n", x, y);
29 }
30 return 0;
31 }
当然上面的exgcd函数还可以写的简洁一些:
1 void exgcd(int a, int b, int& d, int& x, int& y){
2 if(!b){
3 x=1, y=0, d=a;
4 }else{
5 exgcd(b, a%b, d, y, x);
6 y-=x*(a/b);
7 }
8 }
我就是我,颜色不一样的烟火 --- geloutingyu