算法:逆元

逆元

定义

一个数 a a a的倒数 a − 1 a^{-1} a1满足 a × a − 1 = 1 a \times a^{-1} = 1 a×a1=1。取 a a a的逆元 ( a m o d    b ) − 1 (a \mod b)^{-1} (amodb)1满足 ( a m o d    b ) × ( a m o d    b ) − 1 m o d    b = 1 (a \mod b) \times (a \mod b)^{-1} \mod b = 1 (amodb)×(amodb)1modb=1。其中 b b b为质数, a a a的逆元 ( a m o d    b ) − 1 = a b − 2 m o d    b (a \mod b)^{-1} = a^{b-2} \mod b (amodb)1=ab2modb

证明

由费马小定理得 a b − 1 m o d    b = 1 a^{b-1} \mod b = 1 ab1modb=1,即 ( a b − 2 m o d    b ) × ( a m o d    b ) m o d    b = 1 (a^{b-2} \mod b) \times (a \mod b) \mod b = 1 (ab2modb)×(amodb)modb=1,故 ( a m o d    b ) − 1 = a b − 2 m o d    b (a \mod b)^{-1} = a^{b-2} \mod b (amodb)1=ab2modb
费马小定理简单证明如下:取 A = { 1 , 2 , … , b − 1 } A = \{1,2, \dots ,b-1\} A={1,2,,b1},则 A m o d    b = { 1 , 2 , … , b − 1 } A \mod b = \{1,2, \dots ,b-1\} Amodb={1,2,,b1};取 a × A = { a , 2 a , … , ( b − 1 ) a } a \times A = \{a,2a, \dots, (b-1)a\} a×A={a,2a,,(b1)a},则 a × A m o d    b = { 1 , 2 , … , b − 1 } a \times A \mod b = \{1,2, \dots ,b-1\} a×Amodb={1,2,,b1}仍然成立(此处可见下面证明)。取 A A A中所有元素相乘得 S S S,取 a × A a \times A a×A中所有元素相乘得 a b − 1 × S a^{b-1} \times S ab1×S,由 { S m o d    b = ( b − 1 ) ! m o d    b a b − 1 × S m o d    b = ( b − 1 ) ! m o d    b \left\{\begin{array}{cc} S \mod b = (b-1)! \mod b\\ a^{b-1} \times S \mod b = (b-1)! \mod b \end{array}\right. {Smodb=(b1)!modbab1×Smodb=(b1)!modb a b − 1 m o d    b = 1 a^{b-1} \mod b = 1 ab1modb=1
下面用反证法证明 a × A m o d &ThinSpace;&ThinSpace; b = { 1 , 2 , … , b − 1 } a \times A \mod b = \{1,2, \dots ,b-1\} a×Amodb={1,2,,b1}。对于任意 x , y ∈ a × A , x &lt; y x,y \in a \times A, x \lt y x,ya×A,x<y,假设 x m o d &ThinSpace;&ThinSpace; b = y m o d &ThinSpace;&ThinSpace; b x \mod b = y \mod b xmodb=ymodb,那么 ( y − x ) m o d &ThinSpace;&ThinSpace; b = 0 (y-x) \mod b = 0 (yx)modb=0,由 { y m o d &ThinSpace;&ThinSpace; a = 0 x m o d &ThinSpace;&ThinSpace; a = 0 \left\{\begin{array}{cc} y \mod a = 0\\ x \mod a = 0 \end{array}\right. {ymoda=0xmoda=0 ( y − x ) m o d &ThinSpace;&ThinSpace; a = 0 (y-x) \mod a = 0 (yx)moda=0,由 b b b为质数得 l c m ( a , b ) = a × b lcm(a, b) = a \times b lcm(a,b)=a×b,故 ( y − x ) m o d &ThinSpace;&ThinSpace; ( a × b ) = 0 (y-x) \mod (a \times b) = 0 (yx)mod(a×b)=0,因此 y − x ≥ a × b y-x \ge a \times b yxa×b,与 x , y ∈ a × A x,y \in a \times A x,ya×A矛盾,由此可得 x m o d &ThinSpace;&ThinSpace; b ≠ y m o d &ThinSpace;&ThinSpace; b x \mod b \ne y \mod b xmodb̸=ymodb。因此 a × A m o d &ThinSpace;&ThinSpace; b a \times A \mod b a×Amodb ( b − 1 ) (b-1) (b1)个互不相同的元素,即 a × A m o d &ThinSpace;&ThinSpace; b = { 1 , 2 , … , b − 1 } a \times A \mod b = \{1,2, \dots ,b-1\} a×Amodb={1,2,,b1}

思路

利用快速幂 a a a的逆元 a b − 2 m o d &ThinSpace;&ThinSpace; b a^{b-2} \mod b ab2modb

时间复杂度

O ( log ⁡ n ) O(\log n) O(logn)

模板

#include "FP.h"

typedef long long LL;
const LL MOD = 1e9+7;  // the divisor of answer

/**
  * @param a: the number a
  * @return: the inverse of a
  * @other: FP is Fast Power 
  */
LL INV(LL a) {
  return FP(a, MOD-2);
}

应用1

求组合数 C n m m o d &ThinSpace;&ThinSpace; b C_n^m \mod b Cnmmodb。由 C n m = n ! m ! ( n − m ) ! C_n^m = \frac {n!}{m!(n-m)!} Cnm=m!(nm)!n! C n m m o d &ThinSpace;&ThinSpace; b = n ! m ! ( n − m ) ! m o d &ThinSpace;&ThinSpace; b = ( n ! m o d &ThinSpace;&ThinSpace; b ) × ( m ! m o d &ThinSpace;&ThinSpace; b ) − 1 × ( ( n − m ) ! m o d &ThinSpace;&ThinSpace; b ) − 1 m o d &ThinSpace;&ThinSpace; b C_n^{m} \mod b = \frac {n!}{m!(n-m)!} \mod b = (n! \mod b) \times (m! \mod b)^{-1}\times((n-m)! \mod b)^{-1}\mod b Cnmmodb=m!(nm)!n!modb=(n!modb)×(m!modb)1×((nm)!modb)1modb。先预处理 1 ! , 2 ! , … , n ! 1!,2!,\dots,n! 1!,2!,,n!,时间复杂度为 O ( n ) O(n) O(n),再直接求 C n m m o d &ThinSpace;&ThinSpace; b C_n^m \mod b Cnmmodb,时间复杂度为 O ( 1 ) O(1) O(1)

模板1

#include "INV.h"

const LL N = 1e6+10;  // the maximum number

LL fac[N];  // the factorial of numbers
LL inv[N];  // the inverse of factorial

/**
  * @other: initialize fac and inv
  */
void init() {
  inv[0] = fac[0] = 1;  // 0! = 1, INV(1) = 1
  for (int i = 1; i < N; ++i) {
    fac[i] = fac[i-1] * i % MOD;  // i! = (i-1)! * i
    inv[i] = INV(fac[i]);
  }
}

/**
  * @param n: the number n
  * @param m: the number m
  * @return: C(n, m)
  */
LL C(LL n, LL m) {
  return fac[n] * inv[m] % MOD * inv[n-m] % MOD;
}

应用2

已知 p , q , b p,q,b p,q,b,求 a a a满足 a × p m o d &ThinSpace;&ThinSpace; b = q m o d &ThinSpace;&ThinSpace; b a \times p \mod b = q \mod b a×pmodb=qmodb。由 ( a × p m o d &ThinSpace;&ThinSpace; b ) × ( p m o d &ThinSpace;&ThinSpace; b ) − 1 = ( q m o d &ThinSpace;&ThinSpace; b ) × ( p m o d &ThinSpace;&ThinSpace; b ) − 1 (a \times p \mod b) \times (p \mod b)^{-1} = (q \mod b) \times (p \mod b)^{-1} (a×pmodb)×(pmodb)1=(qmodb)×(pmodb)1 a = ( q m o d &ThinSpace;&ThinSpace; b ) × ( p m o d &ThinSpace;&ThinSpace; b ) − 1 a = (q \mod b) \times (p \mod b)^{-1} a=(qmodb)×(pmodb)1

模板2

#include "INV.h"

/**
  * @param p: the number p
  * @param q: the number q
  * @return: the number a
  */
LL cal(LL p, LL q) {
  return q * INV(p) % MOD;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值