数论(补充)
$$ \texttt{HN-SDFZ} $$
数论
对没错还是数论
更新栏
$upd2023.6.5$更新了一些 $\text{Markdown}$ 的东西。
$upd2023.6.21$又更新了一些 $\text{Markdown}$ 的语法。
Question:为什么写这一篇
Answer:前面我的数论文章因为出了不知名bug导致有些知识点没记得上去,这一篇作为补充
所以我们正式开始
欧几里得算法
又称辗转相除法
时间复杂度:$O(\log(a+b))$
示例代码:
int gcd(int a,int b){
return b == 0 ? a : gcd(b,a % b);
}
证明:
-
设$\gcd(a,b) = c$,则 $a = c \times x,b = c \times y //x,y∈Z$
-
那么:$(a - b) = c \times x + c \times y = c \times (x + y)$, 同时:$a \bmod b = ax$
-
也就是说:$a,b$ 两个数都是由最大公约数 $c$ 推出来的,$a,b$ 相减 / 取模都不会改变这个最大公约数 $c$
-
而 $a,b$ 通过不断相减 / 取模来迭代,会使得 $a,b$ 越来越小直至一方完全被消掉(变为$0$)
大整数$\gcd$
-
$a < b$ 时,$\gcd(a,b) = \gcd(b,a)$
-
$a = b$ 时,$\gcd(a,b) = a$
-
$a,b$ 同为偶数时,$\gcd(a,b) = 2\gcd(a/2,b/2)$
-
$a$ 为偶数 $b$ 为奇数时,$\gcd(a,b)=\gcd(a/2,b)$
-
$a$ 为奇数 $b$ 为偶数时,$\gcd(a,b)=\gcd(a,b/2)$
-
$a,b$ 同为奇数时,$\gcd(a,b)=\gcd(a-b,b)$
这个算法又称“更相减损术”
示例代码:
int gcd(int a,int b){
if (a < b) return gcd(b,a);
if (a == b) return a;
if (a & 1 == 0) return b & 1 == 0 ? 2 * gcd(a >> 1,b >> 1) : gcd(a >> 1,b);
return b & 1 == 0 ? gcd(a,b >> 1) : gcd(a - b,b);
}
裴蜀定理
对任何整数 $a,b$,关于二元一次线性方程 $ax+by=m$,当且仅当 $m$ 是 $\gcd(a,b)$ 的倍数时有解
该方程如果有解,必然有无穷多组解,每组解都称为裴蜀数,可以用欧几里得算法求得
推论:$a,b$ 互质的充要条件是存在整数 $x,y$ 使得 $ax+by=1$,这一推论还可以推广到更多元的情况
扩展欧几里得算法
此算法用于求方程 $ax+by=c$ 的整数解,其中 $c=\gcd(a,b)$ 根据裴蜀定理,该方程必定有解
根据欧几里得算法有:$\gcd(a,b)=\gcd(b,a\bmod b)$
于是:$ax+by=\gcd(a,b)=\gcd(b,a \bmod b)=bx+(a \bmod b)y$
右边式子把 $a \bmod b$展开:$bx+(a-a \div b \times b)y$
合并同类项:$ay+b(x-a \div b \times y)$
也即:$ax+by=ay+b(x-a \div b \times y)$
意味着,如果 $(x,y)$ 是一组解,那么 $(y,x-a \div b \times y)$ 就是另一组解
这是一张《著名》的表
如方程 $99x+78y=6$,求解 $x,y$ 的过程如下表 $(x=y1,y=x1-[a\div b]\times y)$:
$a$ | $b$ | $[a \div b]$ | $d$ | $x$ | $y$ |
---|---|---|---|---|---|
$99$ | $78$ | $1$ | $3$ | $-22$ | $-28$ |
$78$ | $21$ | $3$ | $3$ | $-6$ | $-22$ |
$21$ | $15$ | $1$ | $3$ | $-4$ | $-6$ |
$15$ | $6$ | $2$ | $3$ | $2$ | $-4$ |
$6$ | $3$ | $2$ | $3$ | $0$ | $-2$ |
$3$ | $0$ | $N/A$ | $3$ | $2$ | $0$ |
可以发现,$(a,b)$ 自上而下,$(x,y)$ 自下而上。
void Exgcd(int a,int b,int &c,int &x,int &y){
if (b == 0){
c = a; x = 1; y = 0;
}
else {
Exgcd(b,a % b,c,y,x);
y -= x * (a / b);
}
}
当我们一直迭代到 $b=0$ 时,有 $c=a$,方程变为 $ax=a$,解为 $(1,0)$