首页 > 其他分享 >exGCD

exGCD

时间:2025-01-10 20:44:08浏览次数:1  
标签:return GCD int exGCD ax a%

File

int GCD(int a,int b){
	if(b==0)return a;
	return GCD(b,a%b);
}

Question 01 [贝祖定理]

根据 ax+by=GCD(a,b)
a,b均为正整数
求x,y的整数值。

Solution

因为ax+by=GCD(a,b)
并且GCD(a,b)=GCD(b,a%b)
所以ax+by=GCD(b,a%b)
由贝祖定理GCD(b,a%b)=bX+a%bY
我们求出x,y和下一层X,Y的关系扔到递归里求解即可
等量代换ax+by=bX+a%bY
又因为a%b=a-(a/b)b (C++向下取整)
所以
ax+by=bX+[a-(a/b)
b]Y
=bX+aY-b(a/b)Y
=aY+b[X-(a/b)Y]
所以得到
x=Y
y=X-(a/b)
Y
但是递归需要出口
当b=0时GCD(a,b)=a
即当b等于0时,ax+by=a
把b代入 ax+0y=a
显然此时x=1
y可以取任意整数
我们根据大多数代码的习惯将其取0

Code

//求解
//exGCD 函数的返回值是GCD(a,b)
//x,y 用引用的方式取回x,y的结果
int exGCD(int a,int b,int &x,int &y){
	if(b==0){
		x=1,y=0;
		return a;
	}
	//刚才得到的式子
	int X,Y;
	int GCD_answer=exGCD(b,a%b,X,Y);
	x=Y;
	y=X-(a/b)*Y;
	return GCD_answer;
}

当然,该式子不是常见形式
我们可以直接把形参中的x,y传进去
用y记录Answer中“X”的值,x记录“Y”的值
此时
x=Y(correct)
y=X
显然y应该-=(a/b)Y
而Y的值被x所记录
所以 y-=(a/b)
x

Code Improved

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

Question 02 [线性同余方程]

根据 ax%m=b
a,b,m均为正整数
求 x
无解输出“Shit!”

Solution

因为 ax%m=b
其等价于 ax=b+km
所以 ax-mk=b
定义 y=-k
所以 ax+my=b
而 Question 01 则是根据 ax+by=GCD(a,b) 求x,y的整数值。
这就要求 b=GCD(a,m)
但是显然有时b不等于GCD(a,b)却仍然有解

example a=3 m=5 b=3
GCD(a,m)=1
但 x=6 是不定方程的解

注意到若 b%GCD(a,b)==0
则 b=BGCD(a,b) B为整数
ax+my=b 变为 ax+my=B
GCD(a,b)
已知求法的是 aX+mY=GCD(a,b)
显然
x=BX
y=B
Y
是原方程的一组解

Code

#include<bits/stdc++.h>
using namespace std;
int exGCD(int a,int b,int &x,int &y){
	if(b==0){
		x=1,y=0;
		return a;
	}
	int GCD_answer=exGCD(b,a%b,y,x);
	y-=(a/b)*x;
	return GCD_answer;
}
int main(){
	int T,a,b,m,x,y,gcd_ans;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d%d",&a,&b,&m);
		gcd_ans=exGCD(a,m,x,y);
		if(b%gcd_ans==0){
			printf("%d\n",(long long)x*b/gcd_ans%m);
		}else{
			puts("Shit!");
		}
	}
}

Question 03 [逆元]

根据 ax%m=1
求 x (a 关于 m 的逆元)
要求 0<x<m
如没有输出“impossible”

Solution

此题为 Question 02 弱化版
ax+my=1
要求 1%GCD(a,m)=0
即 GCD(a,m)=1
即 a,m 互质

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
int exGCD(int a,int b,int &x,int &y){
	if(b==0){
		x=1,y=0;
		return a;
	}
	int GCD_answer=exGCD(b,a%b,y,x);
	y-=(a/b)*x;
	return GCD_answer;
}
signed main(){
	int T,a,m,x,y;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&a,&m);
		if(exGCD(a,m,x,y)==1){
			printf("%d\n",(x%m+m)%m);
		}else{
			puts("impossible");
		}
	}
}

标签:return,GCD,int,exGCD,ax,a%
From: https://www.cnblogs.com/2025ing/p/18664680

相关文章

  • 【模板】exgcd
    #include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=1e6+10;intT,a,b,c,d,x,y,num;intexgcd(inta,intb,int&x,int&y){ if(b==0){ x=1;y=0;returna; } intd=exgcd(b,a%b,x,y); intz=x;x=y;y=z-(a/b)*y......
  • 基础数论 欧拉定理与exgcd
    欧拉定理:若正整数\(a,n\)互质,则\(a^{\varphi(p)}\equiv1(\bmodp)\)推论(扩展欧拉定理):\[a^b\equiv\begin{cases}a^{b\\bmod\\varphi(p)}\\\\\\\\\\gcd(a,p)=1\\a^b\\\\\\\\\\\\\\\\\\\\\\gcd(a,p)!......
  • 二元一次不定方程(Exgcd)(更方便的解法)
    扩展欧几里得算法(Exgcd)裴蜀定理对于任意一组整数\(a,b\),存在一组整数\(x,y\),满足\(ax+by=\gcd(a,b)\)。Proof:考虑数学归纳法。当\(b=0\)时,由于\(\gcd(a,0)=a\),则对于\(ax+0y=a\)这个不定方程,\(x=1\),\(y\)取任意整数。假设存在一组整数\(x,y\),满足$bx+(a\bmodb)y......
  • 推式子——拓展欧几里德算法exgcd
    试求方程\(ax+by=\gcd(a,b)\)的一组整数解,其中\(a\)和\(b\)是给定的数提前准备好一个式子:辗转相除法\[\gcd(a,b)=\gcd(b,a\bmodb)\]同时我们可以注意到,\(\bmod\)的等价版本:\[a\bmodb=a-b\lfloor\frac{a}{b}\rfloor\]开始推式子首先考虑\(b=0\)的情况,因为......
  • exgcd
    裴蜀定理对于任意整数\(a,b\)都存在整数\(x,y\),使得\(ax+by=gcd(a,b)\)扩展欧几里得算法(exgcd)设整数\(a,b,x,y\)满足\(ax+by=gcd(a,b)\)若\(b=0\),则\(x=1\),\(y\)取任意整数若\(b>0\)\[ax+by=gcd(a,b)\]\[=gcd(b,a\mod\b)\]\[=bx_0+(a\mod\b)y_0\]\[=bx_0+(a-......
  • 扩展欧几里得算法(exGcd)
    扩展欧几里得算法(ExtendedEuclideanalgorithm,EXGCD),常用于求\(ax+by=c\)的一组可行解。过程设\(ax_1+by_1=\gcd(a,b)\)\(bx_2+(a\modb)y_2=gcd(b,a\modb)\)由欧几里得算法:\(\gcd(a,b)=gcd(b,a\modb)\)所以:\(ax_1+by_1=bx_2+(a\modb)y_2\)又因为:\(a\mod......
  • exgcd 通解(新)
    可能不全,老文章在这什么是通解,我们知道二元一次方程,是如果只有一个式子,那么解会有无数个,而通解就是指让我们只找到一个解就可以推出其他所有解的式子。注意以下变量都为整数。知道了定义下面就是推式子了,首先设\(x,y\)是\(ax+by=\gcd(a,b)\)的一个解,那么有\[y=\le......
  • [题解]P5656 【模板】二元一次不定方程 (exgcd)
    P5656【模板】二元一次不定方程(exgcd)若存在\(ax+by=c\),则可以根据特解\(x,y\)求出任意通解\(x',y'\):\(\begin{cases}x'=x+k*\frac{b}{\gcd(a,b)}\\y'=y-k*\frac{a}{\gcd(a,b)}\end{cases}(k\in\mathbb{Z})\)求特解的方法是「扩展欧几里得(exgcd)」,如果没接触过可以先阅读......
  • 扩展欧几里得(exgcd)通解及其证明
    exgcd求ax+by=gcd(a,b)中x和y的通解(下面简称通解)什么是通解我们知道二元一次方程,是如果只有一个式子,那么解会有无数个而通解就是指让我们只找到一个解就可以推出其他所有解的式子(注意本证明极其复杂,请直接背模版或感性理解)知道了定义下面就是推式子了首先......
  • P5656 【模版】二元一次不定方程(exgcd)
    综合考查exgcd功力的题目。没有整数解当且仅当\(\gcd(a,b)\nmidc\),直接输出-1。用exgcd解方程\(ax+by=\gcd(a,b)\)得到一组特解\(x_0,y_0\)。对原方程变形得到\(a\cdot\dfrac{xc}{\gcd(a,b)}+b\cdot\dfrac{yc}{\gcd(a,b)}=c\),于是有\(ax+by=c\)的一组特解\(x_1=\d......