当前位置: 首页 > article >正文

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

目录

一、欧几里得算法

二、拓展欧几里得算法

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=0
        y = 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=0
        y = 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=0
        y = 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范围内且同余b
	    else //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.kler.cn/a/411107.html

相关文章:

  • pikachu文件上传漏洞通关详解
  • 微软Ignite 2024:建立一个Agentic世界!
  • 使用ENSP实现默认路由
  • WebSocket详解、WebSocket入门案例
  • 【人工智能】PyTorch、TensorFlow 和 Keras 全面解析与对比:深度学习框架的终极指南
  • 【Redis_Day6】Hash类型
  • 算法笔记:滑动窗口
  • 从Full-Text Search全文检索到RAG检索增强
  • 【python】数据可视化之图像处理
  • TailwindCss 总结
  • 【纪念365天】我的创作纪念日
  • CDAF / PDAF 原理 | PDAF、CDAF 和 LAAF 对比 | 图像清晰度评价指标
  • 【Linux系统】—— 基本指令(四)
  • Kotlin DSL Gradle 指南
  • MYSQL 表的增删改查(上)
  • qt ubuntu i386 系统
  • 【MySQL系列】通过创建新表备份`password`字段
  • c++:面向对象三大特性--继承
  • 数据结构 【二叉树(上)】
  • c++学习:json库例子
  • Spark SQL大数据分析快速上手-Hive安装
  • 【设计模式】【行为型模式(Behavioral Patterns)】之命令模式(Command Pattern)
  • Vue进阶面试题(三)
  • Python和R统计检验比较各组之间的免疫浸润
  • 【IEEE出版 | ISBN: 979-8-3315-0796-1 | 高录用稳检索】 2025神经网络与智能优化国际研讨会(NNIO 2025)
  • 中国科学院大学研究生学术英语读写教程 Unit6 Biology TextA 原文和翻译