首页 > 其他分享 >扩展欧几里得(exgcd(a,b))

扩展欧几里得(exgcd(a,b))

时间:2023-01-05 09:56:37浏览次数:56  
标签:gcd int 欧几里得 扩展 exgcd ret y1 x1

回顾

        由贝祖定理可知:ax+by=gcd(a,b)

        (a,y)为一组解

       (x+kb,y-ka)也为解

        所以有无数组解

一、扩展欧几里得算法

        x,y为整数,ax+by=gcd(a,b),求解一组x,y使得上式成立。

二、算法推导

        1.由欧几里得(辗转相除法)可知:

      

 

 

          2.递归边界为:b==0时,x=1,y=0

         推导:由欧几里得(辗转相除法)可知:

                    gcd(a,b)=gcd(b,a%b)

                    的边界条件时    r=0时

                   即gcd(a,0)=a

                   a*x1+0*y1=a

                   我们可以构造一组x1,y1

                   x1=1,y1可以为任意数

                   不妨  x1=1,y1=0

                   那么  x1=1,y1=0就是一组解。

         (由此依次往回返,令x=y1,y=x1-a/b*y1,就可以得到ax+by=gcd(a,b)的一组解(x,y).)

        3.如果ax+by=c,c为gcd(a,b),c=p*gcd(a,b),我们如何找到整数解(x,y)使得ax+by=c成立呢?

        推导:假设ax1+by1=gcd(a,b)    式子1

                   由上可知:(x1,y1)的求解方法已知

                   始终可以找到(x1,y1)

                   让式子1两边乘p:apx1+bpy1=p*gcd(a,b)=c

                   所以:x=px1,y=py1(这样就找到了一组解)

                   其实求ax+by=c的解(x,y)

                   令p=c/gcd(a,b)

                   就是求:a/p*x+b/p*y=gcd(a,b)的整数解

三、求解步骤

1.求gcd(a,b)求解(x1,y1),ax1+by1=gcd(a,b)

2.求q=c/gcd(a,b)

3.x=qx1,y=qy1

(由贝祖定理可知,也可以推出无数组解)

四、算法实现

1.代码一:

#include<bits/stdc++.h>

using namespace std;

int exgcd(int a,int b,int &x,int &y)

{    int ret,tmp;

     if(b==0)

     {

        x=1;y=0;return a;}

        ret=exgcd(b,a%b,x,y);

        tmp=x;x=y;y=tmp-a/b*y;

        return ret;

      }

int  main()

{

         int a,b,x,y,z;

         scanf("%d%d",&a,&b);

         z=exgcd(a,b,x,y);

         printf("%d %d %d\n",z,x,y);

         return 0;

}

思考:此时求出的整数解(x,y)并不能保证x为最小整数,若要保证x为最小整数怎么办?

综上可知,只要让:x=(x%b+b)%b,y=(z-a*x)/b

                               利用ax+by=1(ret=gcd(a,b))

                               y=(ret-ax)/b

2.代码二:

#include<bits/stdc++.h>

using namespace std;

int exgcd(int a,int b,int &x,int &y)

{    int ret,tmp;

     if(b==0)

     {

        x=1;y=0;return a;}

        ret=exgcd(b,a%b,x,y);

        tmp=x;x=y;y=tmp-a/b*y;

        return ret;

      }

int  main()

{

         int a,b,x,y,z;

         scanf("%d%d",&a,&b);

         z=exgcd(a,b,x,y);

         x=(x%b+b)%b;

         y=(z-a*x)/b;

         printf("%d %d %d\n",z,x,y);

         return 0;

}

 

标签:gcd,int,欧几里得,扩展,exgcd,ret,y1,x1
From: https://www.cnblogs.com/ddfy198811/p/17025511.html

相关文章

  • csrf相关知识、auth认证模块、扩展auth_user表
    csrf相关知识、auth认证模块、扩展auth_user表目录csrf相关知识、auth认证模块、扩展auth_user表csrf跨站请求伪造csrf攻击原理图解csrf校验策略csrf相关装饰器auth认证模......
  • 不容错过这十款 GNOME Shell 扩展
    当GNOME ​​Shell​(即GNOME3)最初进军 ​​Linux 世界时,众多批评人士指出其灵活性有所欠缺。当初外观有所突破的GNOME确实会给生产效率带来一些影响,然而它多年来一......
  • Jenkins实践指南-09-pipeline 扩展
    5.pipeline扩展  [作者:Surpassme]如果在大量使用pipelin后,会发现Jenkins内置的功能并不能满足我们的需求,这时就需要pipeline扩展。5.1pipeline中使用函数  ......
  • ECAD的领域建模和SysML扩展
    https://modeling-languages.com/sysml-extension-ecad-electrical-cable-design/作者JordiCabot对ECAD(计算机辅助电子设计)的核心概念做了领域建模,并设计了SysML扩展(profi......
  • es6 解构赋值 扩展运算符 字符串模板 等
    解构赋值<template><div><h1>解构赋值</h1></div></template><script>exportdefault{name:"demo4",mounted(){//以前......
  • 上海0~5V模拟量采集扩展IO模块
    1.1、简介DAM模块可实现2/4路模拟量和2/4路热电阻PT100/PT1000温度信号测量。模块通讯接口为RS-485口,MODBUS-RTU通讯协议。DC9~36V电源供电。DAM模块可应用于各......
  • Spring 中最常用的 11 个扩展点
    转自https://mp.weixin.qq.com/s/CFjHtLbD6cAjfDhGJHtYwA 之前给大家写过一篇Bean的生命周期,非常受欢迎,里面其实介绍了Bean生命周期中所有的扩展点。今天给大家带......
  • Parity Game(奇偶游戏)(POJ1733、AcWing 239)(并查集)(扩展域写法+边带权写法)
    题目小A和小B在玩一个游戏。首先,小A写了一个由0和1组成的序列S,长度为N。然后,小B向小A提出了M个问题。在每个问题中,小B指定两个数l和r,小A回答S[l......
  • 13-存储器扩展技术
    //io扩展#include"reg52.h"voidDelay(unsignedchart){ while(t--); }voidSelectHC573(unsignedcharn){ switch(n) { case4: P2=(P2&0x1f)|0x8......
  • JavaScript-扩展阅读
    JavaScript-扩展阅读学习目标能够知道解释性语言和编译型语言的特点能够知道标识符不能是关键字或保留字1.解释型语言和编译型语言1.概述2.执行过程2.标识......