首页 > 其他分享 >exgcd 学习笔记

exgcd 学习笔记

时间:2023-12-24 11:45:27浏览次数:34  
标签:gcd 笔记 学习 满足 exgcd ax y2 mod

定义

又名扩展欧几里得算法(辗转相除法)

是用来求 \(ax+by=gcd(a,b)\) 中未知数的算法


算法证明

拿到一组 \(a,b\) ,设 \(G=gcd(a,b)\)

目标:求出满足 \(ax+by=G(1)\) 的 \(x\) 与 \(y\)

如果 已知一组 \(x2,y2\) ,满足 \(bx2+\) \((a\) \(mod\) \(b)y2=G(2)\)

此时结合 \((1)(2)\) 得
\(ax+by=\) \(bx2+\) \((a\) \(mod\) \(b)y2(3)\)

那么当 如果 满足时,目标就成了求满足 \((3)\) 的 \(x,y\),其中 \(a,b,x2,y2\) 均已知

根据取模运算是 \(a\) \(mod\) \(b=a-b*(a/b)\)
所以方程 \((3)\) 实则是

\(ax+by=\) \(bx2+\) \((a-b*(a/b))y2\)

\(->\) \(ax+by=bx2+ay2-b*(a/b)y2\)

\(->\) \(ax+by=ay2+b(x2-(a/b)y2)\)

那么在根据方程 \(ax+by=G(1)\) 得出一组必然的解:

\(x=y2,y=x2-(a/b)y2(4)\)

可见只需求出 \(x2,y2\) ,就能求出正确的 \(x,y\),问题就转化成了求 \(x2,y2\)

将方程 \((1)\) 与 \((2)\) 对比一下:

\(ax+by=G(1)\)

\(bx2+\) \((a\) \(mod\) \(b)y2=G(2)\)

发现原方程的 \(a\) 变成了 \(b\),原方程的 \(b\) 变成了 \(a\) 而已

所以新的方程也可以看做 \(ax+by=G\) 的形式,然后按照上面的程序进行下来,发现问题又变为求 \(x3,y3\) 再求 \(x4,y4\) \(......\) 即一个递归的过程

递归过程中 \(a,b\) 不断被替换为 \(b,a\) \(mod\) \(b\),这个过程和普通的欧几里得是一样的,所以最后会出现 \(a(n)=G,b(n)=0\)

那么这特就是最后一层,此时就要直接返回了,需要一组 \(x(n),y(n)\) 满足 \(a(n)x(n)+b(n)y(n)=G(5)\),然而 \(a(n)=G,b(n)=0\),所以只要 \((5)\) 的 \(x(n)\) 取 \(1\) 就必定满足了,\(y(n)\) 就随便取个 \(0\) 就行了

最后一层结束后,就开始返回,知道最上一层,每一层都可以通过下一层的 \(x(k+1),y(k+1)\) 求出当前层的 \(x(k),y(k)\)

整个过程就是:以辗转相除的方式向下递进,不断缩小系数,保证会出现有确定解的最后一层


例题

题目链接 同余方程

问题处理

题目问的是满足 \(ax\) \(mod\) \(b=1\) 的最小正整数(a,b均为正整数)

问题可以转化成求 \(ax+by=1\) 中 \(x\) 的值,其中 \(y\) 是个引入的辅助数(y一定是一个负数,但是写成 \(+\) 的形式以便 \(exgcd\) 算法)

问题仍需转化,\(exgcd\) 求得是 \(ax+by=gcd(a,b)\),所以求方程 \(ax+by=m\) 必须满足的条件就是 \(m\) \(mod\) \(gcd(a,b)=0\)


简单证明一下:

由最大公因数的定义,\(a,b\) 均是 \(gcd(a,b)\) 的倍数,因为 \(m=ax+by\),所以 \(m\) 一定是 \(gcd(a,b)\) 的倍数,即 \(m\) \(mod\) \(gcd(a,b)=0\)


可得这道题中,必须满足 \(1\) \(mod\) \(gcd(a,b)=0\),那么 \(gcd(a,b)\) 就必须等于 \(1\) 了,即 \(a,b\) 互质(数据一定是满足的)

之后通过上述的 \(exgcd\) 算法即可,但是题目要求 \(x\) 的最小值,仅仅 \(exgcd\) 无法满足,所以需要答案处理


答案处理

求出来的 \(x,y\) 仅仅满足 \(ax+by=1\),而 \(x\) 不一定是最小正整数解。有可能太大,也可能是负数

解决方案是:\(x\) 批量地减去或加上 \(b\),能保证 \(ax+by=1\),因为:

\(ax+by=1\)

\(->\) \(ax+by+k*ba-k*ba=1\)

\(->\) \(a(x+kb)+(y-ka)b=1\)

1.显然这并不会把方程中的任何整数变为非整数

2.加上或减去 \(b\) 不会使 \(x\) 错过任何解,可以这么理解:


已经求出一组 \(x,y\) 使得 \(ax+by=1\),也就是 \((1-ax)/b=y\),\(y\) 是整数,可见目前 \(1-ax\) 是 \(b\) 的倍数

现在给 \(x\) 加上 \(kb\)(k为整数),则变为:

\((1-a(x+kb))/b\)

\(=(1-ax)/b+ak\)

仍满足其为 \(b\) 的倍数,由此当 \(x\) 的变化量为 \(b\) 的倍数时,等式仍满足


因此到最后,如果 \(x\) 太小就不断 \(+b\) 直到 \(>=0\),反之则一直减直到最小正整数值,就是这么写

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

总代码如下

#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
template<typename Tp> inline void read(Tp&x)
{
    x=0;register bool z=1;
    register char c=getchar();
    for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
    for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    x=(z?x:~x+1);
}
int a,b,x,y;
int exgcd(int a,int b,int &x,int &y)
{
    if(b==0) {x=1;y=0;return a;}
    int d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
signed main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    read(a),read(b);
    exgcd(a,b,x,y);
    x=(x%b+b)%b;
    cout<<x;
}

标签:gcd,笔记,学习,满足,exgcd,ax,y2,mod
From: https://www.cnblogs.com/Charlieljk/p/17923681.html

相关文章

  • Go 语言学习指南:变量、循环、函数、数据类型、Web 框架等全面解析
    学习基础知识掌握Go语言的常见概念,如变量、循环、条件语句、函数、数据类型等等。深入了解Go基础知识的好起点是查阅Go官方文档文章链接:Go编程语言详解:用途、特性、与Python和C++的比较基本语法了解Go语言的基本语法,包括Go程序的执行方式、包引入、主函数等Go......
  • Go 语言学习指南:变量、循环、函数、数据类型、Web 框架等全面解析
    学习基础知识掌握Go语言的常见概念,如变量、循环、条件语句、函数、数据类型等等。深入了解Go基础知识的好起点是查阅Go官方文档文章链接:Go编程语言详解:用途、特性、与Python和C++的比较基本语法了解Go语言的基本语法,包括Go程序的执行方式、包引入、主函数等Go......
  • 2023-2024-1 20231304 《计算机基础与程序设计》第十三周学习总结
    2023-2024-120231304《计算机基础与程序设计》第十三周学习总结作业信息这个作业属于哪个课程2023-2024-1-计算机基础与程序设计这个作业要求在哪里2023-2024-1计算机基础与程序设计第十三周作业这个作业的目标自学教材《C语言程序设计》第12章并完成云班课测试......
  • 2023-2024-1 20231406 《计算机基础与程序设计》第十三周学习总结
    2023-2024-120231406《计算机基础与程序设计》第十三周学习总结作业信息这个作业属于哪个课程2023-2024-1-计算机基础与程序设计这个作业要求在哪里2023-2024-1计算机基础与程序设计第十三周作业这个作业的目标自学《C语言程序设计》第12章并完成云班课测试......
  • JVM虚拟机系统性学习-JVM调优实战之内存溢出、高并发场景调优
    调优实战-内存溢出的定位与分析首先,对于以下代码如果造成内存溢出该如何进行定位呢?通过jmap与MAT工具进行定位分析代码如下:publicclassTestJvmOutOfMemory{publicstaticvoidmain(String[]args){List<Object>list=newArrayList<>();for(int......
  • 2023-2024-1 20231405《计算机基础与程序设计》第十三周学习总结
    2023-2024-120231405《计算机基础与程序设计》第十三周学习总结作业信息作业属于哪个课程https://edu.cnblogs.com/campus/besti/2023-2024-1-CFAP作业要求在哪里https://edu.cnblogs.com/campus/besti/2023-2024-1-CFAP/homework/13009作业的目标自学......
  • 2d物理引擎学习 - 角运动
    角运动(AngularMotion)或叫转动(RotationalMotion)相关公式1) 瞬时角速度(angularvelocity):ω =Δ弧度/Δt,单位:弧度/秒,方向:逆时针旋转,沿转轴向上;顺时针旋转,沿转轴向下; 2)角加速度:a=(ω1-ω0)/t,单位:弧度/秒2,方向:同角速度方向 3) 线速度:即计算单位时间内走过......
  • ml.net例子笔记8-生成式AI-大模型LLM
    生成式AI生成式AI是指能够通过学习数据和语言,生成新的、在某种程度上相似的输出,这种技术由深度学习特别是神经网络的快速发展推动。一、数据:AI的燃料首先,要理解生成式AI,我们必须了解它的基础——数据。数据是AI的燃料,没有数据,AI就无法运行。在生成式AI中,我们需要大量的高质量......
  • 学期:2023-2024-1 学号:20231426 《计算机基础与程序设计》第十三周学习总结
    作业信息这个作业属于哪个课程2022-2023-1-计算机基础与程序设计这个作业要求在哪里2022-2023-1计算机基础与程序设计作业这个作业的目标通过教材内容了解结构体作业正文https://www.cnblogs.com/hhaxx/p/17923969.html教材学习内容总结《计算科学概论》......
  • 2023-2024-1 学号20231318《计算机基础与程序设计》第十三周学习总结
    作业信息这个作业属于哪个课程2023-2024-1-计算机基础与程序设计这个作业要求在哪里2023-2024-1计算机基础与程序设计第十三周作业这个作业的目标自学教材《C语言程序设计》第12章并完成云班课测试。作业正文2023-2024-1学号20231318《计算机基础与程序设计》......