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;
    }
    
  • 相关阅读:
    活着的目标
    Online Judge(OJ)搭建——2、数据库,SQL语句
    《Docker 实战》第三章 Docker Hub 寻宝游戏
    2017年计划
    IDEA 问题 & 解决
    IDEA 自动化配置
    bzoj 3796: Mushroom追妹纸【二分+后缀数组+st表】
    CF487E Tourists【圆方树+tarjan+multiset+树剖+线段树】
    bzoj 1023: [SHOI2008]cactus仙人掌图【tarjan+dp+单调队列】
    bzoj 4316: 小C的独立集【仙人掌dp】
  • 原文地址:https://www.cnblogs.com/CDOI-24374/p/12853932.html
Copyright © 2011-2022 走看看