快速幂求逆元—逆元求解的证明以及理解

简单理解

求逆元首先要有两个数,a、p,求解a % p的乘法逆元,设a % p = b,那么就是求b的乘法逆元。

首先要说的是,当a % p == 0的时候,就没有乘法逆元了。

假设b的乘法逆元是b^-1

求出的乘法逆元有个主要的性质就是
b ∗ b − 1 % p = 1 b * b^{-1} \% p = 1 bb1%p=1


在算法中,如果结果需要模上一个数,在计算的过程中,除以一个数都要变成乘上这个数的逆元,因为计算过程中除法不能和乘法,模运算等其他运算混着算,不然会错。主要就是这个功能,算是一个工具,求组合数的时候可能会用到。

求逆元

给定b、m,其中m为质数,求b模m的乘法逆元

对于任意整数 a, 满足b|a(b整除a),设存在整数一个x,满足
a / b ≡ a ∗ x ( m o d    m ) a/b\equiv a*x(mod\ \ m) a/bax(mod  m)
可以推导得
1 / b ≡ x ( m o d    m ) 1/b\equiv x (mod\ \ m) 1/bx(mod  m)
x即为b模m的乘法逆元
1 ≡ b ∗ b − 1 ( m o d    m ) 1 \equiv b * b^{-1} (mod\ \ m) 1bb1(mod  m)
由费马小定理可知
1 ≡ b ( m − 1 ) ( m o d    m ) 1 \equiv b^{(m-1)} (mod\ \ m) 1b(m1)(mod  m)
带入可得
b ∗ b − 1 ≡ b ( m − 1 ) ( m o d    m ) b * b^{-1} \equiv b^{(m - 1)} (mod\ \ m) bb1b(m1)(mod  m)

最终可得
b − 1 ≡ b ( m − 2 ) ( m o d    m ) b^{-1} \equiv b^{(m - 2)} (mod\ \ m) b1b(m2)(mod  m)
证明可得

对于a,p两个正整数,其中p为质数。

a % p == 0则逆元不存在

当逆元存在时

a模p0 ~ p - 1的乘法逆元是
a p − 2 a^{p - 2} ap2

Code

快速幂

C++

#include <iostream>

using namespace std;

typedef long long ll;

ll ksm(ll a, ll b, int mod)
{
    ll res = 1;
    while (b)
    {
        if (b & 1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}

int main()
{
    int n;
    cin >> n;
    while (n--)
    {
        ll a, p;
        cin >> a >> p;
        if (a % p == 0)
        {
            cout << "impossible" << endl;
        }
        else
        {
            cout << ksm(a, p - 2, p) << endl;
        }
    }
    return 0;
}

Java

import java.util.*;

public class Main
{
    static long ksm(long a, long b, long p)
    {
        long res = 1;
        while(b != 0)
        {
            if (b % 2 == 1)
            {
                res = res * a % p;
            }
            a = a * a % p;
            b /= 2;
        }
        return res;
    }
    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        for (int i = 1; i <= n; i++)
        {
            int a = in.nextInt();
            int p = in.nextInt();
            if (a % p == 0)
            {
                System.out.println("impossible");
            }
            else 
            {
                System.out.println(ksm(a, p - 2, p));
            }
        }
        in.close();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值