【原创】更相减损术 stein算法 欧几里得算法 拓展欧几里得算法 扩展欧几里得算法 逆元的计算与筛法 解模线性方程

欧几里得

说在前面

数论学复习 Part 6。
然后再来一章CRT和组合数,就飞往概率,以此为跳板去向DP。
计划很美啊你。

P.S. 这么说来拉格朗日插值可以说是数论学复习的Part 0了啊。

有一个*龙门粗口**这就是祖安人打招呼的方式*博主在以前发了一篇*儒雅随和*博客,也是讲这个的,虽然写的很*祖安粗口*,但证明还是可堪一看的,(反正是借鉴来的)。

为什么我还会记得多年前的我写博客的亚子呢?

更相减损术 辗转相减法

可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。

g c d ( a , b ) = g c d ( b , a − b ) gcd(a,b)=gcd(b,a-b) gcd(a,b)=gcd(b,ab)

int gcd(int a,int b)
{
	if(a<b) swap(a,b);
	return b?gcd(b,a-b):a;
}

再加上“可半者半之”。

int gcd(int a,int b)
{
	if(a<b) swap(a,b);
	if(a&1) a>>=1;
	if(b&1) b>>=1;
	return b?gcd(b,a-b):a;
}

P . S . 更 相 损 减 术 本 来 是 用 来 约 分 的 , 所 以 “ 可 半 者 半 之 ” 这 句 话 被 狭 义 理 解 为 分 子 分 母 都 是 偶 数 时 约 掉 2 。 而 我 纯 路 人 , 看 到 可 半 者 半 之 就 直 接 断 章 取 义 了 。 P.S. 更相损减术本来是用来约分的,所以“可半者半之”这句话被狭义理解为分子分母都是偶数时约掉2。\\ 而我纯路人,看到可半者半之就直接断章取义了。 P.S.2

这样的话,stein算法和辗转相减法一模一样。 ( 中 国 数 学 领 先 外 国 1700 年 ! ) \xcancel{(中国数学领先外国1700年!)} (1700)

原理是一个数 d d d它整除 a a a b b b的话,它就整除 a , b a,b a,b的任意线性组合即 d ∣ p a + q b     ( p , q ∈ Z ) d\mid pa+qb~~~(p,q\in Z) dpa+qb   (p,qZ)

证明私以为完全不需要了。

欧几里得算法 辗转相除法

g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a\%b) gcd(a,b)=gcd(b,a%b)
模运算是什么?就是多次反复地减直到减不动。
就是多次调用上一个算法。
正确性就更不用赘述了。

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

贝祖(裴蜀)定理

对于任意整数 a , b a,b a,b,一定存在整数 x , y x,y x,y,使得 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)
特别的,如果 a , b a,b a,b互质,就一定存在整数 x , y x,y x,y满足 a x + b y = 1 ax+by=1 ax+by=1

g c d ( a , b ) = d gcd(a,b)=d gcd(a,b)=d a = p d , b = q d a=pd,b=qd a=pd,b=qd,则 a x + b y = g c d ( a , b )    ⟺    p x + q y = 1 ax+by=gcd(a,b)\iff px+qy=1 ax+by=gcd(a,b)px+qy=1。易知 g c d ( p , q ) = 1 gcd(p,q)=1 gcd(p,q)=1
也就是说把所有一般命题转到了“特别的”命题上来。
怎么证明存在性问题?简单啊,给出一组 ( x , y ) (x,y) (x,y)不就好了吗?
原式    ⟺    p x ≡ 1 m o d    q \iff px\equiv 1\mod q px1modq
就是求p关于q的一个逆元,这个逆元的存在性我已经在之前不用贝祖证明出来了(1.1),现在就不再赘述一次。
在这里插入图片描述
P.S.换一个等价命题应该会证得舒服点,比如 a c ≡ b c m o d    p , ( c , p ) = 1 → a ≡ b m o d    p ac\equiv bc\mod p,(c,p)=1\to a\equiv b \mod p acbcmodp,(c,p)=1abmodp

拓展欧几里得算法

拓展欧几里得算法能够在辗转相除的同时求出一组 x , y x,y x,y使得 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)

怎么在辗转相除的时候求呢?我们要看 g c d ( b , a % b ) gcd(b,a\%b) gcd(b,a%b)是吧?
我们设已经辗转相除求出了 b x 0 + ( a % b ) y 0 = g c d ( b , a % b ) bx_0+(a\%b)y_0=gcd(b,a\%b) bx0+(a%b)y0=gcd(b,a%b),然后试图用 x 0 , y 0 x_0,y_0 x0,y0递推出 x , y x,y x,y

因为 g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a\%b) gcd(a,b)=gcd(b,a%b),所以有 a x + b y = b x 0 + ( a % b ) y 0 ax+by=bx_0+(a\%b)y_0 ax+by=bx0+(a%b)y0。设 a = k b + r a=kb+r a=kb+r,则 原 方 程    ⟺    ( k b + r ) x + b y = b x 0 + r y 0    ⟺    b ( k x + y ) + r x = b x 0 + r y 0 原方程\iff (kb+r)x+by=bx_0+ry_0\iff b(kx+y)+rx=bx_0+ry_0 (kb+r)x+by=bx0+ry0b(kx+y)+rx=bx0+ry0
然后随便多项式恒等定理一下就得到 { k x + y = x 0 x = y 0 ⇒ { x = y 0 y = x 0 − k y 0 = x 0 − ⌊ a b ⌋ y 0 \begin{cases}kx+y=x_0\\x=y_0\end{cases}\Rarr\begin{cases}x=y_0\\ y=x_0-ky_0=x_0-\lfloor\frac{a}{b}\rfloor y_0 \end{cases} {kx+y=x0x=y0{x=y0y=x0ky0=x0bay0

然后到最后 b = 0 , a = g c d b=0,a=gcd b=0,a=gcd的时候,有 x k = 1 , y k = 0 x_k=1,y_k=0 xk=1,yk=0

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

或者

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

逆元

定义

除法怎么取模?
小数分数怎么取模?整除、整数的概念都没有了,你怎么取模?
那怎么除法呢?
怎么规避小数分数呢?
5 2 = 2.5 \frac{5}{2}=2.5 25=2.5的话, 5 = 2 ∗ 2.5 5=2*2.5 5=22.5
所以乘法就行了。

我们如果说一个数 a a a关于 p p p的逆元是 a − 1 a^{-1} a1的话,就等价于定义 x a m o d    p = x a − 1 m o d    p \frac{x}{a}\mod p=xa^{-1}\mod p axmodp=xa1modp
要求 a × a − 1 ≡ 1 m o d    p a\times a^{-1}\equiv 1\mod p a×a11modp

这个逆元存在的前提上文也有说, a , p a,p a,p要互质。

求法

法一

如果 p p p是质数的话,我们就有费马小定理, a p − 1 ≡ 1 m o d    p a^{p-1}\equiv 1\mod p ap11modp。此时 a a a的逆元显然就是 a × a p − 2 ≡ 1 m o d    p a\times a^{p-2}\equiv 1\mod p a×ap21modp
这个东西据说还叫蒙哥马利快速幂模。

法二

另外一种方法就是用exgcd。
exgcd(a,b,&x,&y)得到的x就是a关于b的逆元,y就是b关于a的逆元。

筛法

给一个数p,递推地求逆元,求出一个范围内所有数关于p的逆元。
那么p肯定是质数或者相对是质数了。

现在正在求 a a a关于 p p p的逆元,设 p = k a + r p=ka+r p=ka+r,则有 k a + r ≡ 0 ( m o d p ) ka+r\equiv0 \pmod p ka+r0(modp),设 a a a的逆元为 a − 1 a^{-1} a1 r r r的逆元是 r − 1 r^{-1} r1,在两边同时乘以 a − 1 r − 1 a^{-1}r^{-1} a1r1,则有 k r − 1 + a − 1 ≡ 0 ( m o d p )    ⟺    a − 1 ≡ − k r − 1 ≡ − ⌊ p a ⌋ ( p m o d    a ) − 1 ( m o d p ) kr^{-1}+a^{-1}\equiv 0\pmod p\iff a^{-1}\equiv -kr^{-1}\equiv -\lfloor \frac{p}{a}\rfloor(p\mod a)^{-1}\pmod p kr1+a10(modp)a1kr1ap(pmoda)1(modp)

inv[0]=inv[1]=1;
for(int i=2;i<=N;i++) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;

解模线性方程

a x + b y = c ax+by=c ax+by=c

首先如果 g c d ( a , b ) ∤ c gcd(a,b)\nmid c gcd(a,b)c的话,肯定无解,因为左边必然是 g c d ( a , b ) gcd(a,b) gcd(a,b)的倍数。
如果 g c d ( a , b ) ∣ c gcd(a,b)\mid c gcd(a,b)c的话,设 c = k × g c d ( a , b ) c=k\times gcd(a,b) c=k×gcd(a,b),那么我们跑一次扩欧,得到 a x 0 + b y 0 = g c d ( a , b ) ax_0+by_0=gcd(a,b) ax0+by0=gcd(a,b)的一组解 ( x 0 , y 0 ) (x_0,y_0) (x0,y0),然后再乘上 k k k就搞定了。
{ x = k x 0 y = k y 0 \begin{cases}x=kx_0\\y=ky_0\end{cases} {x=kx0y=ky0

如果想要求最小正整数解的话,则就 ( x % p + p ) % p (x\%p+p)\%p (x%p+p)%p就是了。

a x ≡ b m o d    p ax\equiv b \mod p axbmodp

和上面那个差不多。

暴力穷举是一种简单但不高效的算法,用于解决某些问题的尝试。它通过遍历所有可能的解来寻找正确的答案。然而,由于它的复杂性较高,当问题规模增大时,暴力穷举算法的执行时间会指数增长。因此,它主要适用于规模较小的问题。 辗转相除法是一种被广泛应用于求解最大公约数的算法。它通过反复用较小数去除较大数,直到余数为0为止。最后,被除数即为最大公约数。辗转相除法的优点是它的执行速度相对较快,适用于解决大数的问题。 更相减损法也是一种用于求解最大公约数的算法。它通过反复用两个数的差值去替换原来的两个数,直到两个数相等为止。最后,相等的数即为最大公约数。更相减损法与辗转相除法相比,更适用于解决较大数值问题,但它的执行时间会受到较大数值差异的影响。 Stein算法是一种高效的求解最大公约数的算法,同时也被称为二进制法。它结合了辗转相除法和更相减损法的优点,并通过移位和减法操作等来加速计算过程。相较于传统的算法Stein算法的执行速度更快,尤其适用于大数运算。 总结来说,暴力穷举适用于规模较小的问题,而辗转相除法、更相减损法和Stein算法则更适合解决求解最大公约数的问题。鉴于每个算法的特点和优缺点,我们可以根据具体问题的要求选择合适的算法来解决。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值