当前位置: 首页 > news >正文

数论-快速幂

快速幂

  • 模板代码
  • 推导过程

求 A^B mod C,时间复杂度 O(logB)

模板代码

using ll = long long;  // 可以在头文件中添加这行ll qmi(ll a, ll b, ll c)
{ll ans = 1;       // 初始化结果为 1a %= c;           // 将 a 取模 c,确保 a 小于 cwhile (b)         // 当 b 不为零时循环{if (b & 1)    // 如果 b 是奇数{ans = (ans * a) % c;  // 更新结果}a = (a * a) % c;  // 将 a 平方并取模 cb >>= 1;          // 将 b 右移一位(相当于除以 2)}return ans;          // 返回结果
}

推导过程

在这里插入图片描述

要计算 ( a × b ) m o d p (a \times b) \bmod p (a×b)modp ,我们已经知道 a = k 1 p + q 1 a=k_1 p+q_1 a=k1p+q1 b = k 2 p + q 2 b=k_2 p+q_2 b=k2p+q2 。接下来我们先回顾一下 a × b a \times b a×b 的表达式:

a × b = k 1 k 2 p 2 + ( k 1 q 2 + q 1 k 2 ) p + q 1 q 2 a \times b=k_1 k_2 p^2+\left(k_1 q_2+q_1 k_2\right) p+q_1 q_2 a×b=k1k2p2+(k1q2+q1k2)p+q1q2

现在我们需要对这个结果取模 p p p ,即计算 ( a × b ) m o d p (a \times b) \bmod p (a×b)modp
逐项取模:

  1. k 1 k 2 p 2 m o d p : k_1 k_2 p^2 \bmod p: k1k2p2modp:
  • p 2 p^2 p2 p p p 的倍数,所以 k 1 k 2 p 2 m o d p = 0 k_1 k_2 p^2 \bmod p=0 k1k2p2modp=0
  1. ( k 1 q 2 + q 1 k 2 ) p m o d p \left(k_1 q_2+q_1 k_2\right) p \bmod p (k1q2+q1k2)pmodp :
  • 这一项中有一个 p p p ,所以也是 p p p 的倍数,因此 ( k 1 q 2 + q 1 k 2 ) p m o d p = 0 \left(k_1 q_2+q_1 k_2\right) p \bmod p=0 (k1q2+q1k2)pmodp=0
  1. q 1 q 2 m o d p : q_1 q_2 \bmod p: q1q2modp:
  • 这项中不含 p p p ,所以我们直接取模, q 1 q 2 m o d p q_1 q_2 \bmod p q1q2modp 就是结果。

结论:

( a × b ) m o d p = q 1 q 2 m o d p (a \times b) \bmod p=q_1 q_2 \bmod p (a×b)modp=q1q2modp

因此, ( a × b ) m o d p (a \times b) \bmod p (a×b)modp 等于 q 1 q 2 m o d p ∘ ↓ q_1 q_2 \bmod p_{\circ} \downarrow q1q2modp

例如计算310
在这里插入图片描述

计算步骤:

  1. 初始化:
  • ans = 1 , a = 3 , b = 10 =1, a=3, b=10 =1,a=3,b=10 (二进制 101 0 2 1010_2 10102 ) 。
  1. 第一步 ( b = 1010 _ 2 ) : \left(b=1010 \_2\right): (b=1010_2):
  • 最低位为 0 ,跳过乘法。
  • 更新 a = 9 ( 3 2 ) a=9\left(3^2\right) a=9(32)
  1. 第二步 ( b = 101 _ 2 ) \left(b=101 \_2\right) (b=101_2) :
  • 最低位为 1 ,乘以 ans = 9 × 3 = 27 =9 \times 3=27 =9×3=27
  • 更新 a = 81 ( 9 2 ) a=81\left(9^2\right) a=81(92)
  1. 第三步 ( b = 10 _ 2 ) : \left(b=10 \_2\right): (b=10_2):
  • 最低位为 0 ,跳过乘法。
  • 更新 a = 6561 ( 8 1 2 ) a=6561\left(81^2\right) a=6561(812)
  1. 第四步 ( b = 1 _ 2 ) : \left(b=1 \_2\right): (b=1_2):
  • 最低位为 1 ,乘以 ans = 27 × 6561 = 177147 =27 \times 6561=177147 =27×6561=177147
  • 更新 a = 43046721 ( 656 1 2 ) a=43046721\left(6561^2\right) a=43046721(65612)
    1. 结果:
  • 3 10 = 177147 3^{10}=177147 310=177147

http://www.mrgr.cn/news/27706.html

相关文章:

  • hive表名重命名、rename重命名
  • JWT 过期后 自动刷新方案
  • CSS预编译器:让样式编写更高效的秘密武器(6)
  • Python学习26天
  • 马斯克万卡集群AI数据中心引发的科技涟漪:智算数据中心挑战与机遇的全景洞察
  • 数值分析—绪论:误差
  • IP纯净度对跨境电商有哪些影响
  • Google提出 Speculative RAG:通过草稿机制增强检索增强生成
  • 如何利用UML进行领域建模
  • 05_Python数据类型_列表的相关运算
  • 网络原理2-网络层与数据链路层
  • 日系编曲:电吉他音色制作 拾音器选择 电吉他音色制作逻辑 音箱分类 效果器单块分类
  • 深入理解Python中的魔法参数 *args 和 **kwargs
  • C# 反射之动态生成dll/exe
  • CODESYS标准化编程之输入输出映射
  • 通信工程学习:什么是接入网(AN)中的CF核心功能
  • 电子电气架构——中央计算的软件定义汽车架构
  • 台风,也称为热带气旋,是一种在热带海洋上形成的强烈风暴系统。台风的形成需要满足以下几个条件:
  • Cyber Weekly #24
  • quartz 搭配SQL Server时出现deadlock的解决方案
  • Presto
  • RockyLinux-软件实现RAID5
  • String/StringBuffer/StringBuilder的区别
  • 一文速通calcite结合flink理解SQL从文本变成执行计划详细过程
  • for循环语句
  • 抽象工厂模式(Abstract Factory)