🐋
Blog
算法
算法
  • 算法
  • 基础
    • 高精度
    • 二分
    • 位运算
    • 贪心
    • KMP
    • Master Theorem
    • 前缀和 & 差分
    • sort
    • 双指
  • 数据结构
    • 数据结构模拟
  • 数学
    • 组合数
    • 约数
    • 欧拉函数
    • 扩展欧几里得
    • 高斯消元
    • 容斥原理
    • 线性筛
    • 快速幂
  • 动态规划
    • 背包
    • 字符串匹配
    • 区间DP
  • 图论
    • BFS
    • DFS
由 GitBook 提供支持
在本页
  1. 数学

扩展欧几里得

上一页欧拉函数下一页高斯消元

最后更新于2年前

贝祖等式

给定两个整数 a,ba,ba,b,必存在整数 x,yx,yx,y 使得 ax+by=cax + by = cax+by=c 且 gcd(a,b)∣cgcd(a,b)|cgcd(a,b)∣c。

算法分析

因为

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

可得

bx′+(a−⌊a/b⌋∗b)y′=gcd(b,a%b)bx^{'} + (a - \lfloor a / b \rfloor * b)y^{'} = gcd(b, a\%b)bx′+(a−⌊a/b⌋∗b)y′=gcd(b,a%b)

继而

ay′+b(x′−⌊a/b⌋∗y′)=gcd(b,a%b)=gcd(a,b)ay^{'} + b(x^{'} - \lfloor a / b \rfloor * y^{'}) = gcd(b,a\%b) = gcd(a,b)ay′+b(x′−⌊a/b⌋∗y′)=gcd(b,a%b)=gcd(a,b)

故而

#include<iostream>
#include<algorithm>
using namespace std;

void exgcd(int a, int b, int &x, int &y){
    if (!b){
        x = 1, y = 0;
        return;
    }
    exgcd(b, a % b, y, x);
    y -= a / b * x;
    return;
}

int main(){
    int n; cin >> n;
    while (n -- ){
        int a, b, x, y; cin >> a >> b;
        exgcd(a, b, x, y);
        printf("%d %d\n", x, y);
    }
}

时间复杂度分析

线性同余方程

由

#include<iostream>
#include<algorithm>

using namespace std;
void exgcd(int a, int b, int &x, int &y){
    if (!b){
        x = 1, y = 0;
        return;
    }
    exgcd(b, a % b, y, x);
    y -= a / b * x;
}


int main(){
    int n; cin >> n;
    while (n -- ){
        int a, b, m; cin >> a >> b >> m;
        int x, y;
        exgcd(a, m, x, y);
        int gcd = a * x + m * y;
        if (b % gcd == 0)
            cout << (long long)b / gcd * x % m << endl; 
        else 
            cout << "impossible" << endl;
    }
}
x=y′,y=x′−⌊a/b⌋∗y′x = y^{'},y = x^{'} - \lfloor a / b \rfloor * y^{'}x=y′,y=x′−⌊a/b⌋∗y′

这题的时间复杂度和欧几里得算法一样。欧几里得算法时间复杂度 O(log⁡b)O(\log b)O(logb),总时间复杂度 O(nlog⁡b)O(n \log b)O(nlogb)。

给定 nnn 组数据 ai,bi,mia_i,b_i,m_iai​,bi​,mi​,对于每组数求出一个 xix_ixi​,使其满足 ai∗xi≡bi(modm)a_i*x_i\equiv b_i\pmod mai​∗xi​≡bi​(modm),如果无解则输出 impossible。

ai∗xi≡bi(modm)a_i*x_i\equiv b_i\pmod mai​∗xi​≡bi​(modm)

可得 ∃y∈Z\exists y \in Z∃y∈Z

ax=my+b⇒ax+my′=bax = my + b \Rightarrow ax + my^{'} = bax=my+b⇒ax+my′=b

由之前的贝祖等式可知,只要 gcd(a,m)∣bgcd(a,m)|bgcd(a,m)∣b,我们就可以利用扩展欧几里得算法求解线性同余方程。