GCD&exGCD 学习笔记

GCD

int do_gcd(int p,int q){
	if(!q)return p;
	else return do_gcd(q,p%q);
}

Time: \(O(logn)\)

  • 有一个定理:\(lcm(a,b)*gcd(a,b)=a*b\),求完gcd后可以Time:\(O(1)\)求lcm

Ex_GCD (恶心gcd)

过程

裴蜀定理得 \(ax+by=c\) ,当c是gcd(a,b)的倍数的时候,才能有解

那么从基础的地方开始:如何求 \(ax+by=gcd(a,b)\) ? 因为解决完这个问题后, 答案再乘上 \(a/\gcd(a,b)\) 就行了

解法:(来源于oi-wiki )

\(a x_{1}+b y_{1}=\operatorname{gcd}(a, b)\)

\(b x_{2}+(a \bmod b) y_{2}=\operatorname{gcd}(b, a \bmod b)\)

由欧几里得定理可知: \(\quad \operatorname{gcd}(a, b)=\operatorname{gcd}(b, a \bmod b)\)

所以 \(a x_{1}+b y_{1}=b x_{2}+(a \bmod b) y_{2}\)

又因为 \(a \bmod b=a-\left(\left\lfloor\frac{a}{b}\right\rfloor \times b\right)\)

所以 \(a x_{1}+b y_{1}=b x_{2}+\left(a-\left(\left\lfloor\frac{a}{b}\right\rfloor \times b\right)\right) y_{2}\)

\(a x_{1}+b y_{1}=a y_{2}+b x_{2}-\left\lfloor\frac{a}{b}\right\rfloor \times b y_{2}=a y_{2}+b\left(x_{2}-\left\lfloor\frac{a}{b}\right\rfloor y_{2}\right)\)

因为 \(a=a, b=b,\) 所以 \(x_{1}=y_{2}, y_{1}=x_{2}-\left\lfloor\frac{a}{b}\right\rfloor y_{2}\)

将 \(x_{2}, y_{2}\) 不断代入递归求解直至 gcd (最大公约数, 下同) 为 \(0\) 递归 \(x=1, y=0\) 回去求解。

  • 结论:两个式子可以得出 \(x_{1}=y_{2}, y_{1}=x_{2}-\left\lfloor\frac{a}{b}\right\rfloor y_{2}\) 直到\(x=1,y=0\)时返回0

代码

void exgcd(int p,int q,int &x,int &y){
	if(!q){x=1,y=0;return ;}
    exgcd(q,p%q,x,y);
    int tmp=x;
    x=y,y=tmp-(p/q)*y;
    return z;
}

Time:\(O(logn)\) ( 因为p和q和gcd复杂度是一样的,而终止条件也是p=0 )

用递归做可以让常数稍微减少,但问题不大就懒得写了qwq

上一篇:luogu五一数学数论专题


下一篇:题解:「MtOI2019」幽灵乐团 / 莫比乌斯反演基础练习题