各种逆元推导

逆元

求解一(费马小定理)

p p 是一个质数,并且 a % p 0 a \% p \not= 0 ,则有 a p 1 1 ( m o d p ) a ^ {p - 1} \equiv 1 \pmod p a p 2 a 1 a ^ {p - 2} \equiv a ^ {-1} ,即可得到逆元。

int quic_pow(int a, int n, int mod) {
    int ans = 1;
    while(n) {
        if(n & 1) ans = (ans * a) % mod;
        a = (a * a) % mod;
        n >>= 1;
    }
    return ans;
}
int inv(int a, int p) {
    return quick_pow(a, p - 2, p);
}

求解二(拓展欧几里德)

我们知道拓展欧几里德算法可以求解 a x + b y = g c d ( a , b ) ax + by = gcd(a, b) ,对逆元考虑假设有 a x + b y = 1 a * x + b * y = 1 那么显然有 a x 1 ( m o d b ) a * x \equiv 1 \pmod b ,这不就出来了吗, x x 就是 a a b b 下的逆元,当然了这里也要有 a , b a, b 互质。

int exgcd(int a, int b, int & x, int & y) {
    if(!b) {
        x = 1, y = 0;
        return a;
    }
    int gcd = exgcd(b, a % b, x, y);
    int temp = x;
    x = y;
    y = temp - a / b * y;
    return gcd;
}
int main() {
    int a, mod, inv, t;
    exgcd(a, mod, inv, t);
    return 0;
}

求解三(线性求解逆元)

我们假定有 m o d = k a + b , k = m o d a , b = m o d % a b < a mod = k * a + b, k = \frac{mod} {a}, b = mod \% a,b < a

k a + b 0 ( m o d m o d ) k * a + b \equiv 0 \pmod {mod}

同时乘以 a 1 b 1 a ^ {-1}b^{-1}

k b 1 + a 1 0 ( m o d m o d ) k * b ^{-1} + a ^{-1} \equiv 0 \pmod {mod}

a 1 k b 1 ( m o d m o d ) a ^{-1} \equiv -k * b ^ {-1} \pmod {mod}

a 1 m o d b 1 k b 1 ( m o d m o d ) a ^ {-1} \equiv mod * b ^{-1} - k * b^ {-1} \pmod {mod}

所以我们就推导完了。

int inv[n], mod = 100007, n = mod;
for(int i = 2; i < n; i++) {
    inv[2] = ((p - p / i) * inv[p % i]) % mod
}

求解四( C n m C _{n} ^ {m} 中的逆元求解)

a ! 1 = n a! ^ {-1} = n 那么我们不难发现 ( a 1 ) ! 1 = a ! 1 a (a - 1) ! ^ {-1} = a! ^{-1} * a

void init() {
    fac[0] = 1;
    for(int i = 1; i < N; i++)
        fac[i] = (fac[i - 1] * i) % mod;
    inv[N - 1] = qpow(fac[N - 1], mod - 2);
    for(int i = N - 2; i >= 0; i--)
        inv[i] = (inv[i + 1] * (i + 1)) % mod;
}

猜你喜欢

转载自blog.csdn.net/weixin_45483201/article/details/107600325