zoukankan      html  css  js  c++  java
  • 浅谈 exgcd

    众所周知欧几里得算法是:

    [gcd(a,b)=gcd(b,amod \,b) ]

    也叫辗转相除法。

    拓展欧几里得算法(exgcd),可以用来找到形如 (ax+by=gcd(a,b)) 的方程的一组特解

    由裴蜀定理知,原方程一定有解。

    我们利用辗转相除法(普通欧几里得算法)。

    我们设 (d=gcd(a,b))

    我们可以知道,我们辗转相除法的边界是 (a=d,b=0),此时我们可以知道 (a) 就是最大公约数,我们还可以知道,在这时一定有一解为 (x=1,y=0),即 (1 imes a+0 imes b=d)

    我们知道 (gcd(a,b)=gcd(b,amod b)),如果我们可以推导出每一次的解 (x)(y),与相除后的解 (x')(y') 的关系;我们就可以算出其中的一个解了,((x)(y) 相当于是 (a) 和 $b (的解,)x'$ 和 (y')(a) 变成了 (b)(b) 变成了 (amod b) 时的解(辗转相除))。

    轻易得知:

    (egin{cases} ax+by=d\ bx'+(amod b)y'=d end{cases})

    则:

    [egin{aligned} bx'+left(a-bleftlfloordfrac{a}{b} ight floor ight)y'&=d\ bx'+ay'-bleftlfloordfrac{a}{b} ight floor y'&=d\ ay'+b(x'-leftlfloordfrac{a}{b} ight floor y')&=d\ ext{解得:}&egin{cases} x=y'\y=x'-leftlfloordfrac{a}{b} ight floor y' end{cases} end{aligned} ]

    然后我们知道 (x)(x')(y)(y'), 的关系后就可以求解了:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    void exgcd(int a,int b,int& x,int& y) //x.y也可以用pair返回,这里用了引用
    {
    	if (!b){x=1;y=0;return ;}     //边界
    	gcd(b,a%b);                   //辗转相除
    	int tmp=y;y=x-(a/b)*y;x=tmp;  //套公式
    }
    int main()
    {
    	int a,b,x,y;
    	scanf("%d %d",&a,&b);
    	exgcd(a,b,x,y);
    	printf("%d %d",x,y);
    	return 0;
    }
    
  • 相关阅读:
    闪回还原点解析
    先有鸡还是先有蛋的争论
    Android缓存处理
    hdu 1398 Square Coins (母函数)
    JSON具体解释
    【LeetCode】String to Integer (atoi) 解题报告
    【Linux探索之旅】第一部分第四课:磁盘分区,并完毕Ubuntu安装
    MySQL排序:SELECT ORDER BY
    架构师速成7.3-devops为什么非常重要
    升级Linux内核导致vmware无法使用(vmnet模块无法编译)解决方式
  • 原文地址:https://www.cnblogs.com/CDOI-24374/p/12853932.html
Copyright © 2011-2022 走看看