信奥数学-(扩展)欧几里得算法、裴蜀定理(贝祖定理)
信奥数学-(扩展)欧几里得算法、裴蜀定理(贝祖定理)
扩展欧几里得算法(Extended Euclidean algorithm, EXGCD),常用于求 \(ax+by=gcd(a,b)\) 的一组可行解。
令
\(ax1+by1=gcd(a,b)\)
\(bx2+(a~mod~b)y2=gcd(b, a~mod ~b)\)
由欧几里得定理知
\(gcd(a,b)=gcd(b, a~mod ~b)\)
所以
\(ax1+by1=bx2+(a~mod~b)y2\)
又因为
\(a~mod~b=a-(\lfloor \frac{a}{b}\rfloor * b)\)
所以
\(ax1+by1=bx2+(a-(\lfloor \frac{a}{b}\rfloor * b))y2\)
所以
\(ax1+by1=ay2+bx2-\lfloor \frac{a}{b}\rfloor * by2\)
所以
\(ax1+by1=ay2+b(x2-\lfloor \frac{a}{b}\rfloor)y2\)
又因为 a=a b=b 根据等式定理
\(x1=y2 , y1=x2-\lfloor \frac{a}{b} \rfloor y2\)
将x y不断递归知道b=0时 gcd(a,b)=a
ax+by =a
所以 ax+0=a 所以x=1 同时取最小的一个y为0 为最小的一组 x y的解,作为递归边界
然后根据上面推导公式,则可以计算其他解
P4549 【模板】裴蜀定理
https://www.luogu.com.cn/problem/P4549
#include<bits/stdc++.h>
using namespace std;
int n,ans;
//裴蜀定理 ax+by=gcd(a,b)
int gcd(int a,int b){
if(b==0) return a;
return gcd(b,a%b);
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
int tmp;
cin>>tmp;
ans=gcd(ans,abs(tmp));//如果b为负数 取绝对值
}
cout<<ans;
return 0;
}
P1082 [NOIP2012 提高组] 同余方程
https://www.luogu.com.cn/problem/P1082
扩展欧几里得定理
#include<iostream>
typedef long long ll;
using namespace std;
ll x ,y;
//扩展欧几里得算法求乘法逆元
void exgcd(ll a,ll b){
if(b==0){
x=1;
y=0;
return;
}
exgcd(b,a%b);
ll tx = x;
x = y;
y = tx - a/b * y;
}
int main(){
ll a,b;
cin >> a >> b;
exgcd(a,b);
x = (x%b+b)%b;
cout << x;
return 0;
}
两个闹钟
https://www.acwing.com/problem/content/description/4382/
[选]
P1516 青蛙的约会
https://www.luogu.com.cn/problem/P1516
P2054 [AHOI2005] 洗牌
https://www.luogu.com.cn/problem/P2054
P2421 [NOI2002] 荒岛野人
https://www.luogu.com.cn/problem/P2421
作者:newcode 更多资源请关注纽扣编程微信公众号

从事机器人比赛、机器人等级考试、少儿scratch编程、信息学奥赛等研究学习

浙公网安备 33010602011771号