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;
    }
    
  • 相关阅读:
    51nod 1134 最长递增子序列
    51nod 1135 原根
    51nod 1136 欧拉函数
    51nod 1137 矩阵乘法
    51nod 1174 区间中最大的数
    51nod 1079 中国剩余定理
    51nod 1181 质数中的质数(质数筛法)
    伪共享(False Sharing)和缓存行(Cache Line)
    mybatis 批量 操作数据
    java开发中beancopy比较
  • 原文地址:https://www.cnblogs.com/CDOI-24374/p/12853932.html
Copyright © 2011-2022 走看看