欧几里得与扩展欧几里得

欧几里德算法

定义 gcd ⁡ ( a , b ) \gcd(a,b) gcd(a,b) a , b a,b a,b 的最大公约数

假设 gcd ⁡ ( a , b ) ≡ gcd ⁡ ( b , a % b ) \gcd(a,b)\equiv\gcd(b,a\%b) gcd(a,b)gcd(b,a%b)

k = a % b k=a\%b k=a%b,设 k ′ = gcd ⁡ ( a , b ) k'=\gcd(a,b) k=gcd(a,b)

a = x k ′ , b = y k ′ a=xk',b=yk' a=xk,b=yk { x , y } ∈ [ 1 , ∞ ] \{x,y\}\in[1,∞] {x,y}[1,] x ⊥ y x\bot y xy

∴ k = a % b = a − k ′ ′ b = x k ′ − k ′ ′ y k ′ = ( x − k ′ ′ y ) k ′ ∴ k=a\%b=a-k''b=xk'-k''yk'=(x-k''y)k' k=a%b=akb=xkkyk=(xky)k

∴ k = ( x − k ′ ′ y ) k ′ ∴ k=(x-k''y)k' k=(xky)k

∵ b = y k ′ ∵ b=yk' b=yk

假设 ( x − k ′ ′ y ) (x-k''y) (xky) y y y 不互质

y = p q , ( x − k ′ ′ y ) = p ′ q y=pq,(x-k''y)=p'q y=pq,(xky)=pq

y y y 代入 ( x − k ′ ′ y ) (x-k''y) (xky)

∴ x − k ′ ′ y = x − p q k ′ ′ = p ′ q ∴ x-k''y=x-pqk''=p'q xky=xpqk=pq

∴ x − p q k ′ ′ = p ′ q ∴ x-pqk''=p'q xpqk=pq

∴ x = p ′ q + p q k ′ ′ ∴ x=p'q+pqk'' x=pq+pqk

提公因式

x = ( p ′ + p k ′ ′ ) q x=(p'+pk'')q x=(p+pk)q

∵ a = x k ′ = ( p ′ + p k ′ ′ ) q k ′ ∵ a=xk'=(p'+pk'')qk' a=xk=(p+pk)qk

∵ b = y k ′ = p q k ′ ∵ b=yk'=pqk' b=yk=pqk

∴ gcd ⁡ ( a , b ) = q k ′ ∴ \gcd(a,b)=qk' gcd(a,b)=qk

与原命题不符, ∴ ( x − k ′ ′ y ) ⊥ y ∴ (x-k''y)\bot y (xky)y

∵ gcd ⁡ ( b , a % b ) = gcd ⁡ ( b , k ) = gcd ⁡ ( y k ′ , ( x − k ′ ′ y ) k ′ ) ∵ \gcd(b,a\%b)=\gcd(b,k)=\gcd(yk',(x-k''y)k') gcd(b,a%b)=gcd(b,k)=gcd(yk,(xky)k)

∵ ( x − k ′ ′ y ) ⊥ y ∵ (x-k''y) \bot y (xky)y

∴ gcd ⁡ ( b , a % b ) ≡ k ′ ≡ gcd ⁡ ( a , b ) ∴ \gcd(b,a\%b)\equiv k'\equiv \gcd(a,b) gcd(b,a%b)kgcd(a,b)

a % b = 0 , gcd ⁡ ( a , b ) = b a\%b=0,\gcd(a,b)=b a%b=0,gcd(a,b)=b

所以就有了代码

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

对于斐波那契数列

gcd ⁡ ( f ( n ) , f ( m ) ) = f ( gcd ⁡ ( n , m ) ) \gcd(f(n),f(m))=f(\gcd(n,m)) gcd(f(n),f(m))=f(gcd(n,m))

扩展欧几里德

假设存在 { x , y } , \{x,y\}, {x,y}, 使得 gcd ⁡ ( a , b ) ≡ a x + b y \gcd(a,b)\equiv ax+by gcd(a,b)ax+by

b = 0 b=0 b=0

gcd ⁡ ( a , b ) = a , x = 1 , y = 0 \gcd(a,b)=a,x=1,y=0 gcd(a,b)=a,x=1,y=0

b ≠ 0 b\neq0 b=0

a x ′ + b y ′ = gcd ⁡ ( a , b ) ax'+by'=\gcd(a,b) ax+by=gcd(a,b)

b x ′ ′ + ( a % b ) y ′ ′ = gcd ⁡ ( b , a % b ) bx''+(a\%b)y''=\gcd(b,a\%b) bx+(a%b)y=gcd(b,a%b)

∵ a % b ≡ a − ⌊ a b ⌋ × b ∵ a\%b\equiv a-\lfloor\frac{a}{b}\rfloor\times b a%baba×b

∴ a x ′ + b y ′ = b x ′ ′ + ( a − ⌊ a b ⌋ × b ) y ′ ′ ∴ ax'+by'=bx''+(a-\lfloor\frac{a}{b}\rfloor\times b)y'' ax+by=bx+(aba×b)y

∴ a x ′ + b y ′ = b x ′ ′ + a y ′ ′ − ⌊ a b ⌋ b y ′ ′ ∴ ax'+by'=bx''+ay''-\lfloor\frac{a}{b}\rfloor by'' ax+by=bx+aybaby

∴ a x ′ + b y ′ = a y ′ ′ + b ( x ′ ′ − ⌊ a b ⌋ y ′ ′ ) ∴ ax'+by'=ay''+b(x''-\lfloor\frac{a}{b}\rfloor y'') ax+by=ay+b(xbay)

∴ x ′ = y ′ ′ , y ′ = ( x ′ ′ − ⌊ a b ⌋ y ′ ′ ) ∴ x'=y'',y'=(x''-\lfloor\frac{a}{b}\rfloor y'') x=y,y=(xbay)

$∵ $ 当 b = 0 b=0 b=0 时存在解

∴ ∴ 解存在

然后我们就有代码了

inline void exgcd(int a,int b) {
    if(b) {
        exgcd(b,a%b);
        int t=x; x=y;
        y=k-a/b*y;
    } else y=(x=1)-1;
}

贝祖定理

定义: a x + b y = c ax+by=c ax+by=c ,满足 { x , y } ∈ [ 1 , ∞ ] \{x,y\}\in[1,∞] {x,y}[1,],且 gcd ⁡ ( a , b ) ∣ c \gcd(a,b)|c gcd(a,b)c

s = gcd ⁡ ( a , b ) s=\gcd(a,b) s=gcd(a,b),则 s ∣ a s|a sa s ∣ b s|b sb

s ∣ a x s|ax sax s ∣ b y s|by sby

k ′ ∈ [ 1 , ∞ ] k'\in[1,∞] k[1,]

c = gcd ⁡ ( a , b ) × k ′ c=\gcd(a,b)\times k' c=gcd(a,b)×k

∴ gcd ⁡ ( a , b ) ∣ c ∴ \gcd(a,b)|c gcd(a,b)c 成立

扩展欧几里德解不定方程

对于不定方程 a x + b y = c ax+by=c ax+by=c,设 k ′ = gcd ⁡ ( a , b ) k'=\gcd(a,b) k=gcd(a,b)

∵ ∵ 存在 { x , y } \{x,y\} {x,y} 使得 gcd ⁡ ( a , b ) ≡ a x + b y ≡ k ′ \gcd(a,b) \equiv ax+by \equiv k' gcd(a,b)ax+byk

c % k ′ ≠ 0 c\%k'\neq 0 c%k=0 无解

c % k ′ = 0 c\%k'=0 c%k=0

可用 exgcd \text{exgcd} exgcd 算出 gcd ⁡ ( a , b ) = a x + b y \gcd(a,b)=ax+by gcd(a,b)=ax+by,即 a x + b y = k ′ ax+by=k' ax+by=k 的一组解

解得 x = x 0 , y = y 0 x=x_0,y=y_0 x=x0,y=y0

∴ x 0 × c k ′ , y 0 × c k ′ ∴ x_0\times \frac{c}{k'},y_0\times \frac{c}{k'} x0×kc,y0×kc

∴ x = x 0 × c k ′ × k ′ ′ , y = y 0 × c k ′ × k ′ ′ ∴ x=x_0\times\frac{c}{k'}\times k'',y=y_0\times\frac{c}{k'}\times k'' x=x0×kc×k,y=y0×kc×k

∴ a c k ′ ′ x 0 k ′ + b c k ′ ′ y 0 k ′ = c ∴ \frac{ack''x_0}{k'}+\frac{bck''y_0}{k'}=c kackx0+kbcky0=c

∴ a c k ′ ′ x 0 + b c k ′ ′ y 0 = c k ′ ∴ ack''x_0+bck''y_0=ck' ackx0+bcky0=ck

∴ ( a x 0 + b y 0 ) c k ′ ′ = c k ′ ∴ (ax_0+by_0)ck''=ck' (ax0+by0)ck=ck

∴ c k ′ k ′ ′ = c k ′ ∴ ck'k''=ck' ckk=ck

∴ k ′ ′ = 1 ∴ k''=1 k=1

∴ x = x 0 × c k ′ , y = y 0 × c k ′ ∴ x=x_0\times \frac{c}{k'},y=y_0\times \frac{c}{k'} x=x0×kc,y=y0×kc

∴ a x 0 × c k ′ + b y 0 × c k ′ = c ∴ ax_0\times\frac{c}{k'}+by_0\times\frac{c}{k'}=c ax0×kc+by0×kc=c

∴ ( a x 0 + b y 0 ) × c k ′ = c ∴ (ax_0+by_0)\times \frac{c}{k'}=c (ax0+by0)×kc=c

∴ a x 0 + b y 0 = k ′ ∴ ax_0+by_0=k' ax0+by0=k

所以此式恒等成立

扩展欧几里德解同余方程

对于同余方程 a x ≡ c m o d    b ax\equiv c \mod b axcmodb

∴ a x − c ≡ 0 m o d    b ∴ ax-c\equiv 0 \mod b axc0modb

∴ a x + b y ≡ c ∴ ax+by\equiv c ax+byc

所以,只要求 exgcd \text{exgcd} exgcd 即可

乘法逆元

通常用于求

a b ( m o d p ) \frac{a}{b} \pmod p ba(modp)

a × x ≡ 1 ( m o d p ) a\times x \equiv 1 \pmod p a×x1(modp)

a a a x x x 互质,则可称 x x x a a a 的逆元,也称 x x x a a a 的倒数

对于

a b ( m o d p ) \frac{a}{b} \pmod p ba(modp)

只需求出

( 1 b ( m o d p ) ) × a (\frac{1}{b} \pmod p)\times a (b1(modp))×a

也就是求出 b b b 的逆元再乘上 a a a

拓展欧几里德解乘法逆元

利用拓展欧几里德解同余方程 a x ≡ c ( m o d p ) ax\equiv c \pmod p axc(modp) c = 1 c=1 c=1 的情况

也就是转换为 a x + b y ≡ 1 ax+by\equiv 1 ax+by1 的情况

然后用 exgcd \text{exgcd} exgcd 求解

快速幂解乘法逆元

通过费马小定理可知, ∀ a ∈ [ 1 , ∞ ] \forall a \in[1,∞] a[1,] 与素数 p p p

a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1 \pmod p ap11(modp)

a x ≡ 1 ( m o d p ) ax\equiv 1 \pmod p ax1(modp)

所以有 a p − 1 ≡ a x ( m o d p ) a^{p-1}\equiv ax \pmod p ap1ax(modp)

所以有 a p − 2 ≡ x ( m o d p ) a^{p-2}\equiv x \pmod p ap2x(modp)

只要用快速幂求出 a p − 2 ( m o d p ) a^{p-2} \pmod p ap2(modp) 的值就行了

线性乘法逆元

对于求一连串数字 ( m o d p ) \pmod p (modp) 的逆元,上面的方法就显得慢

考虑逆元之间的递推关系

首先我们有 1 − 1 ≡ 1 m o d    p 1^{-1}\equiv 1 \mod p 111modp

不妨设 p = k × i + r p=k\times i + r p=k×i+r,也就是 k = ⌊ p i ⌋ k=\lfloor\frac{p}{i}\rfloor k=ip

k × i + r ≡ 0 ( m o d p ) k\times i + r \equiv 0 \pmod p k×i+r0(modp)

乘上 i − 1 × r − 1 i^{-1}\times r^{-1} i1×r1

k × r − 1 + i − 1 ≡ 0 ( m o d p ) k\times r^{-1}+i^{-1}\equiv 0 \pmod p k×r1+i10(modp)

i − 1 ≡ − k × r − 1 ( m o d p ) i^{-1}\equiv-k\times r^{-1} \pmod p i1k×r1(modp)

i − 1 ≡ − ⌊ p i ⌋ × r − 1 ( m o d p ) i^{-1}\equiv-\lfloor\frac{p}{i}\rfloor\times r^{-1} \pmod p i1ip×r1(modp)

i − 1 ≡ − ⌊ p i ⌋ × ( p ( m o d i ) ) − 1 ( m o d p ) i^{-1}\equiv-\lfloor\frac{p}{i}\rfloor\times(p \pmod i)^{-1} \pmod p i1ip×(p(modi))1(modp)

然后我们就有代码了

ans[1]=1;
for(int i=1;i<p;i++) ans[i]=(p-p/i)*ans[p%i]%p;
阶乘逆元

我们有

a n s [ i + 1 ] = 1 ( i + 1 ) ! ans[i+1]=\frac{1}{(i+1)!} ans[i+1]=(i+1)!1

a n s [ i + 1 ] × ( i + 1 ) = i + 1 ( i + 1 ) ! = 1 i = a n s [ i ] ans[i+1]\times (i+1)=\frac{i+1}{(i+1)!}=\frac{1}{i}=ans[i] ans[i+1]×(i+1)=(i+1)!i+1=i1=ans[i]

a n s [ i ] = a n s [ i + 1 ] × ( i + 1 ) ans[i]=ans[i+1]\times (i+1) ans[i]=ans[i+1]×(i+1)

所以就可以从后往前求出所有逆元

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值