首页 > 编程语言 >扩展欧几里得算法

扩展欧几里得算法

时间:2023-08-20 18:33:47浏览次数:43  
标签:int dfrac 欧几里得 扩展 算法 ax bmod define

裴蜀定理

对于任意正整数 \(a,b\),记 \(g=(a,b)\),一定存在整数 \(x,y\),使得 \(ax+by=g\),且能凑出的数一定是 \(g\) 的倍数。

首先由于 \(a,b\) 都是 \(g\) 的倍数,所以能凑出的数必定是 \(g\) 的倍数。

关键在于怎么证明一定存在整数 \(x,y\),使得 \(ax+by=g\)。

下面我们就抛出这个算法。

扩展欧几里得算法

首先引入欧几里得算法。

\(g=\gcd(b,a\bmod b)\)(不知道就回普及组来学的实在太强了)

若 \(b=0\),则 \(g=a\)。

直接在欧几里得算法里添加内容。

我们从边界情况开始考虑。

当 \(b=0\) 时,要求 \(ax+by=ax=\gcd(a,0)=a\),显然 \(x=1,y=0\) 是一组解。

我们在递归的时候将 \(x,y\) 翻转,于是就求得 \(by+(a\bmod b)x=\gcd(b,a\bmod b)=g\)。

根据余数的定义 \(a\bmod b=a-b\lfloor\dfrac{a}{b}\rfloor\)。

代入可得 \(by+(a-b\lfloor\dfrac{a}{b}\rfloor)x=g\)。

我们将 \(a,b\) 系数整理到一块儿。

\(ax+b(y-\lfloor\dfrac{a}{b}\rfloor x)=g\)。

发现这就是我们需要的形式,于是令 \(y=y-\lfloor\dfrac{a}{b}\rfloor x\)。

那怎么求多组解呢?

发现 \(a(x-\dfrac{b}{d})+b(y+\dfrac{a}{d})=ax+by\)。

那么我们据此可以推出所有的解。

令 \(x_0,y_0\) 表示我们求得的解。

则所有解 \(x=x_0-k\dfrac{b}{d},y=y+k\dfrac{a}{d}\)。

据此发现有无数个解。

扩欧直接应用

#include<cstdio>
using namespace std;
#define Ed for(int i=h[x];~i;i=ne[i])
#define Ls(i,l,r) for(int i=l;i<r;++i)
#define Rs(i,l,r) for(int i=l;i>r;--i)
#define Le(i,l,r) for(int i=l;i<=r;++i)
#define Re(i,l,r) for(int i=l;i>=r;--i)
#define L(i,l) for(int i=0;i<l;++i)
#define E(i,l) for(int i=1;i<=l;++i)
#define W(t) while(t--)
#define Wh while

const int N=1;
int n;
int exgcd(int a,int b,int &x,int &y){
    if(!b){
        x=1,y=0;
        return a;
    }
    int d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
    #endif
    scanf("%d",&n);
    W(n){
        int a,b,x,y;
        scanf("%d%d",&a,&b);
        exgcd(a,b,x,y);
        printf("%d %d\n",x,y);
    }
    return 0;
}

应用:求解 \(ax\equiv b\pmod{m}\)(当 \(b=1\) 时,\(x\) 为 \(a\) 的逆元)

题目传送门

考虑变形可得 \(ax=my+b\bmod m\),也可以变为 \(ax=my+b\)(就是将部分的 \(m\) 给 \(b\))。

得 \(ax-my=b\)。

令 \(y'=-y\),\(ax+my'=b\)。

先用扩欧解 \(b=(a,m)\) 的情况,然后先判断是不是倍数,然后扩大 \(\dfrac{b}{(a,m)}\)。

#include<cstdio>
using namespace std;
#define Ed for(int i=h[x];~i;i=ne[i])
#define Ls(i,l,r) for(int i=l;i<r;++i)
#define Rs(i,l,r) for(int i=l;i>r;--i)
#define Le(i,l,r) for(int i=l;i<=r;++i)
#define Re(i,l,r) for(int i=l;i>=r;--i)
#define L(i,l) for(int i=0;i<l;++i)
#define E(i,l) for(int i=1;i<=l;++i)
#define W(t) while(t--)
#define Wh while

const int N=1;
int n;
int exgcd(int a,int b,int &x,int &y){
    if(!b){
        x=1,y=0;
        return a;
    }
    int d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
    #endif
    scanf("%d",&n);
    W(n){
        // printf("n=%d\n",n);
        int a,b,m,x,y;
        scanf("%d%d%d",&a,&b,&m);
        int d=exgcd(a,m,x,y);
        if(b%d)puts("impossible");
        else printf("%lld\n",1ll*b*x/d%m);
    }
    return 0;
}

标签:int,dfrac,欧几里得,扩展,算法,ax,bmod,define
From: https://www.cnblogs.com/wscqwq/p/17644365.html

相关文章

  • STL容器和算法
    目录STL容器和算法基本概念容器容器的分类序列式容器关联式容器vector容器vector的定义vector的赋值vector的大小vector的访问方式vector的元素操作deque容器list容器基本概念迭代器基本概念vector的迭代器迭代器失效算法STL容器和算法基本概念标准模板库,主要分为容器、算法、......
  • 算法总结
    前言:有关于算法的一切的大合集基本数据结构及排序方法手撸完全二叉树/满二叉树红黑树节点分为红色或者黑色;根节点必为黑色;叶子节点都为黑色,且为null;连接红色节点的两个子节点都为黑色(红黑树不会出现相邻的红色节点);从任意节点出发,到其每个叶子节点的路径中包含相同数......
  • 快速幂算法
    快速幂洛谷P1226【模板】快速幂||取余运算#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;llquickpow(lla,llb,llp=10){ //计算a的b次方 if(b==0)return1; intans=1; while(b){ if(b&1){ ans=ans*a%p; } ......
  • 第二十三节 API(算法,lambda,练习)
    常见的七种查找算法:​ 数据结构是数据存储的方式,算法是数据计算的方式。所以在开发中,算法和数据结构息息相关。今天的讲义中会涉及部分数据结构的专业名词,如果各位铁粉有疑惑,可以先看一下哥们后面录制的数据结构,再回头看算法。1.基本查找​ 也叫做顺序查找​说明:顺序......
  • 可扩展的三层代码设计
    可扩展的三层代码设计这次我们根据上面的图,来谈谈一个SOA服务的代码怎么分层才能做到维护起来如丝般顺滑,下面我们一层一层的说。SoaService层SOA层是对外暴露的API层,来表现一些服务能力,打个比方,一个商户服务,可以修改店铺的营业时间,修改营业状态,修改店铺属性等等,这些基础能......
  • UFCFT4-15-3 加密系统算法
    MODULARPROGRAMMECOURSEWORKASSESSMENTSPECIFICATIONModuleDetailsModuleCodeUFCFT4-15-3 Runsem3FIRSTSIT2023/24 ModuleTitleCryptographyModuleLeader ModuleTutorsSMLAUComponentandElementNumberProgram(includingsourcecodeandexecutable)and......
  • 基础入门-算法分析&传输加密&数据格式&密文存储&代码混淆&逆向保护
    基础入门-算法分析&传输加密&数据格式&密文存储&代码混淆&逆向保护基础入门-算法分析&传输加密&数据格式&密文存储&代码混淆&逆向保护传输数据-编码型&加密型等传输格式-常规&JSON&XML等密码存储-Web&系统&三方应用代码混淆-源代码加密&逆向保护加密:1.常见加密编码进制等算法解......
  • 探索编程世界的宝藏:程序员必掌握的20大算法
    #程序员必须掌握哪些算法?#1引言在当今数字化时代,程序员们仍然需要拥有一把解决问题和优化代码的金钥匙。这些钥匙是算法,它们隐藏在计算机科学的宝藏中,等待着我们去发现和掌握。本篇博文将带你踏上一段引人入胜的探险之旅,揭开程序员必须掌握的20大算法的神秘面纱。从冒泡排序到......
  • c++算法之动态规划:01背包
    什么是动态规划?动态规划算法(dynamicprograming),是一种由递推为基础的比贪心更稳定的一种优化策略,为运筹学的一部分。就是通过以递推为基础的手段非暴力求出最值。它的总体思想其实就是一个比较过程:假如你有一个数据,它的价值是x,代价为y,如果用动态规划就是和你不加这个元素和你加......
  • 欧几里得算法(辗转相除法)-- 实现分数计算
    博客地址:https://www.cnblogs.com/zylyehuo/#-*-coding:utf-8-*-"""利用欧几里得算法实现一个分数类,支持分数的四则运算(加法)"""classFraction:def__init__(self,a,b):self.a=aself.b=bx=self.gcd(a,b)se......