扩展欧几里得算法

扩展欧几里得算法

欧几里得算法

设$(a,b)==d$,则$d\mid a,d\mid b$。

假设$(b,a%b)==d_1$,则 $d_1\mid a,d_1\mid a%b$

因为$a%b==a-a/b*b$,所以$d\mid a%b$,所以$d_1\ge d$。

假设$d_1>d$,因为$d_1\mid a%b \rightarrow d_1\mid a - a/b * b \rightarrow d1\mid a \and d_1 \mid b$,所以$(a,b)d_1\and d_1>d$与条件不符,因此$(a,b)(b,a%b)d$。$(a,0)a$,所以当有一个为零的时候就可以求出他们的最大公约数了。

可以理解为不断缩小集合的范围然后留下的就是公共的最小得了。

int gcd(int a, int b) {
return b ? gcd(b, a % b) : a;
}

扩展欧几里得算法

裴蜀定理

有任意正整数a,b,一定存在非零整数x,y,使得

ax + by = (a,b)

首先左边都整除$d$,所以右边是$d$的倍数,因为他是$d$的倍数,所以最小的就是$d==(a,b)$。

利用扩展欧几里得算法就可以求出这样的$x,y$。

发现求最大共约数的时候当$(r_k,0)==r_k$的时候可以使$x=1,y=0$就求出了一组解。

然后再回溯的时候维护一下就可以。

假设到了当前这一层即

$bx+(a-a/bb)y\rightarrow bx+ay-a/bb*y\rightarrow ay+b(x-a/by)$

只需要回溯的时候维护一下即可

int exgcd(int a, int b, int &x, int &y) {
    if (!b) {
		x = 1, y = 0;
        return a;
    }
    int d = exgcd(b, a % b, x, y);
    int k = x;
    x = y;
    y = k - a / b * y;
    return d;
}

我们如果在递归的时候交换一下$x,y$的位置,则有

$by+(a-a/bb)x\rightarrow by+ax-a/bbx \rightarrow ax+b(y-a/bx)$

这样回溯的时候就比较好维护了

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

我们求出来的是一组不确定的解$x_0,y_0$

通解可以表示为$x=x_0+kb/(a,b),y=y_0-ka/(a,b)$

通解不会改变结果。

求最小正整数解$x$对$b/(a,b)$取模即可。

费马小定理

若有a,p(质数)且(a,p)==1,则有$a^{p-1} \equiv1(mod\ p)$

欧拉定理

若(a,n)==1,则$a^{\varphi(n)}\equiv1(mod\ n)$

posted @ 2022-03-31 17:13  枉玊  阅读(62)  评论(0)    收藏  举报