【算法基础:数学知识】4.4 快速幂

快速幂

https://oi-wiki.org/math/binary-exponentiation/

在这里插入图片描述
计算过程:
在这里插入图片描述

例题列表

875. 快速幂⭐⭐⭐⭐⭐(重要!)

https://www.acwing.com/activity/content/problem/content/944/
在这里插入图片描述

求 a ^ b % p,时间复杂度是 O ( log ⁡ b ) O(\log{b}) O(logb)

代码写法1——递归

对于递归写法比较好理解
对于求 m k m o d    p m^k \mod p mkmodp 每次将 k 缩小到原来的一半。

import java.util.*;

public class Main {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        while (n-- != 0) {
            long a = sc.nextInt(), b = sc.nextInt(), p = sc.nextInt();
            System.out.println(qmi(a, b, p));
        }
    }

    static long qmi(long a, long b, long p) {
        if (b == 0) return 1;
        long res = qmi(a, b / 2, p) % p;
        if (b % 2 == 0) return res * res % p;
        else return res * res * a % p;
    }
}

代码写法2——迭代

关于迭代版的解释看一个例子比较清楚:

在这里插入图片描述
对于求 m ^ k % p。
我们预处理出 m 2 0 、 m 2 1 、 m 2 2 、 m 2 3 . . . m^{2^0}、m^{2^1}、m^{2^2}、m^{2^3}... m20m21m22m23... 这里的每一项都是前一项的平方,对应代码中的 t = t * t % p

import java.util.*;

public class Main {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        while (n-- != 0) {
            long a = sc.nextInt(), b = sc.nextInt(), p = sc.nextInt();
            System.out.println(qmi(a, b, p));
        }
    }

    // 迭代版快速幂
    static long qmi(long a, long b, long p) {
        long res = 1 % p, t = a;
        // 把 b 看成二进制数字,哪些位置是 1 就把它乘起来就好了
        while (b != 0) {
            if ((b & 1) == 1) res = res * t % p;
            t = t * t % p;
            b >>= 1;
        }
        return res;
    }
}

递归写法 与 迭代写法的 对比

在这里插入图片描述

876. 快速幂求逆元🚹(需要理解逆元的概念)TODO

https://www.acwing.com/problem/content/878/

在这里插入图片描述

乘法逆元介绍

https://oi-wiki.org/math/number-theory/inverse/

在这里插入图片描述

那么什么是线性同余方程?
在这里插入图片描述

就是希望找到一个数 x,使得 a / b 的结果与 a * x mod m 之后结果相同。

解法代码

在这里插入代码片
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wei *

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值