信奥数学-(扩展)欧几里得算法、裴蜀定理(贝祖定理)

信奥数学-(扩展)欧几里得算法、裴蜀定理(贝祖定理)

扩展欧几里得算法(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

posted @ 2022-06-14 10:18  new-code  阅读(103)  评论(0)    收藏  举报