【算法】欧几里得与拓展欧几里得算法

server/2024/12/2 4:05:03/

目录

一、欧几里得算法

二、拓展欧几里得算法

2.1 裴蜀定理

2.2 拓展欧几里得算法

2.3 例题

三、线性同余方程

3.1 概念

3.2 例题


一、欧几里得算法

欧几里得算法又称辗转相除法,可用于求解两个数的最大公约数

其思路:

  • gcd(a, b) = gcd(b, a%b),其中gcd(a, b)代表a和b的最大公约数
  • 当b=0时,a为最大公约数

例如要求36和24的最大公约数即gcd(36, 24),可转而求gcd(24, 36%24)即gcd(24, 12),再转为求gcd(12, 0),此时最大公约数即为12

其代码实现:

int gcd(int a, int b)
{if(b == 0)return a;return gcd(b, a % b);
}


二、拓展欧几里得算法

2.1 裴蜀定理

  • 若a,b是整数,且d = gcd(a, b),则对于任意的整数x和y,总有ax+by是d的倍数
  • 对于给定的整数x和y,方程ax+by=c有整数解(x, y)的充分必要条件是c是gcd(a, b)的倍数

2.2 拓展欧几里得算法

由裴蜀定理,我们知道对于给定的整数a和b,方程ax + by = gcd(a, b)总有整数解(x, y)

那么,如何求出这个整数解(x, y)?

  1. 由欧几里得算法可得gcd(a, b) = gcd(b, a%b)
  2. 由裴蜀定理,bx' + (a%b)y' = gcd(b, a%b)
  3. 由1和2,得bx' + (a%b)y' = gcd(a, b) 即 ax + by = bx' + (a%b)y'
  4. 由a%b = a - b*(a/b)【注意这里的a/b是向下取整】,得ax + by = bx' + [a - b*(a/b)]y'
  5. 上式整理得a(x-y') - b[x' - y - (a/b)y'] = 0,即x-y'=0、x' - y - (a/b)y'=0
  6. 得x = y',y = x'-(a/b)y'

得到求解后,我们就可以通过递归不断传入x和y来计算整数解(x, y)了。拓展欧几里得的递归终点和欧几里得的终点类似,当b为0时即ax+by = a时返回{x=1,y=0}的解,并通过上一次的结果向下更新

拓展欧几里得算法的代码实现:

int exgcd(int a, int b, int &x, int &y) //扩展欧几里得算法
{if(b == 0) //b为0时结束递归{x = 1; //ax+by=a->x=1,y=0y = 0;return a;}int gcd = exgcd(b, a%b, y, x); //递归求x'和y'y -= (a/b) * x; //此时递归后x=y',y=x',将y=x'-(a/b)y'转为y=y-(a/b)x得y-=(a/b)x return gcd;
}

2.3 例题

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define debug(x) cout << #x << " = " << x << '\n'
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;int n, a, b, x, y;int exgcd(int a, int b, int &x, int &y) //扩展欧几里得算法
{if(b == 0) //b为0时结束递归{x = 1; //ax+by=a->x=1,y=0y = 0;return a;}int gcd = exgcd(b, a%b, y, x); //递归求x'和y'y -= (a/b) * x; //此时递归后x=y',y=x',将y=x'-(a/b)y'转为y=y-(a/b)x得y-=(a/b)x return gcd;
}void solve()
{cin >> n;for(int i = 0;i < n; i++){cin >> a >> b;exgcd(a, b, x, y);cout << x << " " << y << endl;}
}signed main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t = 1;// cin >> t;while (t--)solve();return 0;
}


三、线性同余方程

3.1 概念

线性同余方程ax ≡ b(mod m),要求我们求出一个整数x,使得a和x的乘积模上m等于b

对于这个方程,可以用拓展欧几里得算法求解:

  1. ax ≡ b(mod m)可转化为对于整数x,存在整数y使得ax = my + b
  2. 令y' = -y,则上式转化为ax + my' = b
  3. 用拓展欧几里得算法求ax' + my' = gcd(a, m)
  4. 只要b是gcd(a, m)的倍数则说明方程成立,整数x存在,x = x' * (b / gcd(a, m))

3.2 例题

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define debug(x) cout << #x << " = " << x << '\n'
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;int n, a, b, m, x, y;int exgcd(int a, int b, int &x, int &y) //扩展欧几里得算法
{if(b == 0) //b为0时结束递归{x = 1; //ax+by=a->x=1,y=0y = 0;return a;}int gcd = exgcd(b, a%b, y, x); //递归求x'和y'y -= (a/b) * x; //此时递归后x=y',y=x',将y=x'-(a/b)y'转为y=y-(a/b)x得y-=(a/b)x return gcd;
}void solve()
{cin >> n;for(int i = 0;i < n; i++){cin >> a >> b >> m;int gcd = exgcd(a, m, x, y);if(b % gcd == 0) //b是gcd倍数:成立cout << x * (b / gcd) % m << endl; //为什么要%m?因为可以保证x在int范围内且同余belse //b不是gcd倍数:无解cout << "impossible" << endl;}
}signed main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t = 1;// cin >> t;while (t--)solve();return 0;
}

完.


http://www.ppmy.cn/server/146614.html

相关文章

多数元素

多数元素 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例 1&#xff1a; 输入&#xff1a;nums [3,2,3] 输出&#xff…

2024-11-27 学习人工智能的Day32 神经网络与反向传播

一、神经网络 神经网络神经网络&#xff08;Neural Networks&#xff09;是一种模拟人脑神经元网络结构的计算模型&#xff0c;用于处理复杂的模式识别、分类和预测等任务。 人工神经元是神经网络的基础构建单元&#xff0c;模仿了神武神经元的工作原理&#xff0c;核心功能是…

Supervisor使用教程

文章目录 [toc] Supervisor使用教程平台要求 安装supervisor本文测试的时候是使用Linux的yum安装的&#xff08;其它方式未做测试&#xff09;加入系统守护进行 Supervisor使用教程 在项目中&#xff0c;经常有脚本需要常驻运行的需求。以PHP脚本为例&#xff0c;最简单的方式…

Spring Boot教程之十二: Spring – RestTemplate

Spring – RestTemplate 由于流量大和快速访问服务&#xff0c;REST API越来越受欢迎。REST 不是一种协议或标准方式&#xff0c;而是一组架构约束。它也被称为 RESTful API 或 Web API。当发出客户端请求时&#xff0c;它只是通过 HTTP 将资源状态的表示传输给请求者或端点。传…

SVN迁移至Git,保留commit提交记录

SVN迁移至Git 如何将 SVN 仓库迁移到 Git 并保留提交记录一、生成userinfo.txt二. 使用 git svn clone 命令迁移 SVN 到 Git2.1. 基本命令格式2.2. 示例&#xff1a;从 SVN 克隆到 Git参数说明&#xff1a;2.3 执行的过程遇到的窗口2.4. 迁移过程 三. 将 Git 仓库推送到远程 Gi…

源代码定制编译:构建理想的库 以curl为例

文章目录 源代码curl开发环境下载地址制定理想的库初级进阶如何知道选项名称交叉编译交叉编译工具链配置编译环境设置目标架构库和头文件路径编译代码 源代码 我们在日常中会接触到比较多第三方库&#xff0c;比如 网络库相关&#xff1a; libevent、mongoose、curl图形界面&…

Oracle 19c RAC单节点停机维护硬件

背景 RAC 环境下一台主机硬件光纤卡不定时重启&#xff0c;造成链路会间断几秒&#xff0c;期间数据库会话响应时间随之变长&#xff0c;该光纤卡在硬件厂商的建议下&#xff0c;决定停机更换备件&#xff0c;为保证生产影响最小&#xff0c;决定停掉该节点&#xff0c;另外节…

CSS定位

定位 其中&#xff0c;绝对定位和固定定位会脱离文档流 设置定位之后&#xff1a;可以使用四个方向值进行调整位置&#xff1a;left、top、right、bottom 相对定位 温馨提示 设置定位之后&#xff0c;相对定位和绝对定位他是相对于具有定位的父级元素进行位置调整&#xff0c…