扩展欧几里得

扩展欧几里得

根据我国的某搜索网站,对扩欧的定义如下“ 扩展欧几里德算法是用来在已知a, b求解一组x,y,使它们满足贝祖等式: ax+by = gcd(a, b) =dax+by=gcd(a,b)=d (解一定存在,根据数论中的相关定理 )。”

说人话

简而言之,扩欧就是大佬的凑数(或者叫不定方程???)

首先 我们写一组一看就解不出来的方程 ax+by=cax+by=c

a,b,c,x,y\in za,b,c,x,y∈z

扩欧就是证明这组方程的解的情况

我们考虑 x=k_1gcd(x,y),y=k_2gcd(x,y)x=k
1
​ gcd(x,y),y=k
2
​ gcd(x,y)

所以原式可以看成 (k1a+k2b)gcd(x,y)=c(k1a+k2b)gcd(x,y)=c

所以 cc 一定是 gcd(x,y)gcd(x,y) 的倍数

我们考虑辗转相除的过程,从辗转相除的后一项推出前一项。

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

所以凑出构造方程 bx1+(a%b)y2=gcd(b,a%b)bx1+(a%b)y2=gcd(b,a%b) --后一项的方程

所以, bx1+(a%b)y2=ax+bybx1+(a%b)y2=ax+by

然后又因为 a%b=a-(a/b)a%b=a−(a/b) 的取整*b(取整笔者下文暂时用<[]>代替)

所以 bx1+[a-<a/b>*b]y2=ax+bybx1+[a−<a/b>∗b]y2=ax+by

展开后得 ay2+<x1-[a/b]y2>b=ax+byay2+<x1−[a/b]y2>b=ax+by

笔者当初看到这就懵了。这怎么做啊

事实证明,凑数的力量是伟大的

你“令” x=y2,y=x1-<[a/b]>y2x=y2,y=x1−<[a/b]>y2 不就是原方程的一个解吗?

这就构成了一个递归的过程,递归出口就在当x=1且y=0时。

即 gcd(a,b)1+0b=gcd(a,b)gcd(a,b)∗1+0∗b=gcd(a,b) (因为辗转相减,所以a==gcd(a,b)了)

题目传送门

扩欧模板,

因为这道题可以看做ax-bk=1

所以就妥妥地上了扩欧

#include<bits/stdc++.h>
using namespace std;
int x,y,k;
void exgcd(int a,int b){
    if(b==0){
        x=1;
        y=0;
        return ;
    }
    exgcd(b,a%b);
    k=x;
    x=y;
    y=k-a/b*y;
}
int a,b;
int main(){
    cin>>a>>b;
    exgcd(a,b);
    cout<<(x+b)%b;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值