第二十七章 数论——快速幂与逆元

news2024/11/26 0:49:21

第二十七章 快速幂与扩展欧几里德算法

  • 一、快速幂
    • 1、使用场景
    • 2、算法思路
      • (1)二进制优化思想
      • (2)模运算法则
    • 3、代码实现
      • (1)问题
      • (2)代码
  • 二、快速幂求逆元
    • 1、什么是逆元?
      • (1)同余
      • (2)逆元
    • 2、逆元的求法
      • (1)欧拉定理
      • (2)费马小定理
      • (3)问题
      • (4)求解逆元

一、快速幂

1、使用场景

我们知道,如果我们想计算一个 q k q^k qk,我们可以不断地去乘,但这样的时间复杂度是 O ( k ) O(k) O(k),这个是复杂度就很高了。

而我们的快速幂算法就是为了优化这个过程的,快速幂算法的时间复杂度是 O ( l o g k ) O(logk) O(logk)

2、算法思路

(1)二进制优化思想

快速幂的优化思想其实就是二进制的优化思想。
我们在动态规划中,解决多重背包问题的时候,我们就用到了二进制优化的思想。

那么什么是二进制优化呢?
比如一个数 120 120 120
这个数的二进制表示是: 01111000 0111 1000 01111000
为了更快的表示这个数,我们可以提前准备好这样几个数:
1000 0000,
0100 0000,
0010 0000,
0001 0000,
0000 1000,
0000 0100,
0000 0010,
0000 0001

上面这些数字有什么特点呢?
就是我们任意组合几个上述所写的数字,都能让对应的位置变成1。

那么我们要是想得到我们的120,则需要让对应的位置变成1。

那么我们就需要让0000 0000加上
0100 0000
0010 0000
0001 0000
0000 1000

这几个数加在一起,就是0111 1000

也就是说我们从0算到120,只算了4次。

因此,我们预处理出这些数字:

q 1 , q 2 , q 4 . . . . . q^1,q^2,q^4..... q1,q2,q4.....

因为, q n ∗ q m = q^n*q^m= qnqm= q q q(n+m)

所以相当于我们在指数部分进行了二进制优化。

然后我们去遍历一个数的二进制表示,如果对应的二进制位是1,那么我们就从预处理的表中取出对应的数字。

(2)模运算法则

这种数学问题经常遇到取模操作,所以我们有必要了解一下常见的取模运算法则:
在这里插入图片描述
上述法则来自于百度百科的介绍。

3、代码实现

(1)问题

在这里插入图片描述

(2)代码

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
LL qmi(int a, int b, int p)
{
    LL res = 1 % p;
    while (b)
    {
        if (b & 1) res = res * a % p;
        a = a * (LL)a % p;
        b >>= 1;
    }
    return res;
}
int main()
{
    int n;
    scanf("%d", &n);
    while (n -- )
    {
        int a, b, p;
        scanf("%d%d%d", &a, &b, &p);
        printf("%lld\n", qmi(a, b, p));
    }
    return 0;
}

二、快速幂求逆元

1、什么是逆元?

(1)同余

介绍逆元之前,先介绍一个新的概念:同余

如果 a a a% c = m c=m c=m,并且 b b b% c = m c=m c=m,两个式子的结果是相同的,即余数相同,简称同余

记作: a ≡ b ( m o d   c ) a\equiv b(mod\ c) ab(mod c)

(2)逆元

在数论当中,除法是比较难处理的,因为除法意味着有可能会出现小数。

所以,我们想尽可能地避免除法的出现,而这也是逆元的作用。

如果 a ∣ b a|b ab并且 a b ≡ a ∗ x ( m o d   c ) \frac{a}{b} \equiv a*x(mod\ c) baax(mod c),此时我们的 x x x就称作逆元,记作:b-1

由于二者是同余的,所以我们可以把求 a b   m o d   c \frac{a}{b}\ mod\ c ba mod c的过程,等价为, a ∗ x   m o d   c a*x\ mod\ c ax mod c

这样的话,我们就利用逆元避免了除法的出现。
那么现在的问题就是,我们如何求逆元呢?

2、逆元的求法

(1)欧拉定理

我们曾经介绍过欧拉函数,欧拉函数是用来求解互质的,而欧拉函数通常用 Φ ( n ) \Phi(n) Φ(n)来表示。

如果大家想要了解欧拉函数的话,可以去看作者之前的文章:
欧拉函数的介绍及证明

我们的欧拉定理也用到了欧拉函数。

欧拉定理的内容是:

如果 g c d ( a , n ) ,那么 a Φ ( n ) ≡ 1 ( m o d   n ) 如果gcd(a,n),那么a^{\Phi(n)}\equiv 1(mod\ n) 如果gcd(a,n),那么aΦ(n)1(mod n)

(2)费马小定理

由欧拉函数可知,当 p p p是质数的时候, Φ ( p ) = p − 1 \Phi(p)=p-1 Φ(p)=p1

所以,我们刚刚介绍的欧拉定理中:

如果 g c d ( a , n ) ,那么 a Φ ( n ) ≡ 1 ( m o d   n ) 如果gcd(a,n),那么a^{\Phi(n)}\equiv 1(mod\ n) 如果gcd(a,n),那么aΦ(n)1(mod n)

如果 n n n为质数 p p p,并且 a a a p p p互质,那么 a p − 1 ≡ 1 ( m o d   p ) a^{p-1}\equiv 1(mod \ p) ap11(mod p)

这个就是费马小定理,即 n n n为质数的时候的欧拉定理,可以说,费马小定理是欧拉定理的一个特殊情况。

(3)问题

在这里插入图片描述

(4)求解逆元

我们在回顾一下逆元的定义:
a b ≡ a ∗ x ( m o d   c ) \frac{a}{b} \equiv a*x(mod\ c) baax(mod c)

由于 b ≡ b ( m o d   c ) b \equiv b(mod\ c) bb(mod c)

所以根据同余的一个计算性质:
a b ∗ b ≡ a ∗ x ∗ b ( m o d   c ) \frac{a}{b}*b\equiv a*x*b(mod\ c) babaxb(mod c)

(这个可以百度,作者这里就不证明了。)

所以上述的式子可以化简为:

a ≡ a ∗ x ∗ b ( m o d   c ) a\equiv a*x*b(mod\ c) aaxb(mod c)

再次根据同余的运算性质,我们可以消掉两测的 a a a

即, 1 ≡ x ∗ b ( m o d   c ) 1\equiv x*b(mod\ c) 1xb(mod c)

整理一下即:

x ∗ b ≡ 1 ( m o d   c ) x*b\equiv 1(mod\ c) xb1(mod c)

本道题中,特殊强调了模数是质数,也就是说我们的 c c c是质数,所以可以使用费马小定理。

由费马小定理:

b c − 1 ≡ 1 ( m o d   c ) b^{c-1}\equiv 1(mod\ c) bc11(mod c)

整理一下:

b c − 2 ∗ b ≡ 1 ( m o d   c ) b^{c-2}*b\equiv 1(mod\ c) bc2b1(mod c)

所以我们的 x = b c − 2 x=b^{c-2} x=bc2

所以现在这道题就转换成了快速幂。

因为题目中告诉我们 b b b c c c,我们需要计算的是 b c − 2 b^{c-2} bc2

用题目中给出的字母表示即:
a p − 2 a^{p-2} ap2

这是逆元存在的情况:什么情况下不存在呢?

我们化简后的表达式是:

x ∗ b ≡ 1 ( m o d   c ) x*b\equiv 1(mod\ c) xb1(mod c)

如果说此时,b是c的倍数,那么b%c就是0,不是1。此时不成立。所以我们需要特殊判断一下。

题目说求1–p-1的答案,所以我们还是要取模一下。

代码:

#include<iostream>
using namespace std;
typedef long long ll;
long long qmi(ll a,ll b,ll p)
{
    ll res=1;
    while(b)
    {
        if(b&1)res=(res%p*a%p)%p;
        a=(a%p*a%p)%p;
        b>>=1;
    }
    return res;
}
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        ll a,p;
        cin>>a>>p;
        if(a%p==0)puts("impossible");
        else cout<<qmi(a,p-2,p)<<endl;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/116069.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

结构体位段问题

每一位勇敢努力的少年&#xff0c;必将不负众望&#xff01; 什么是位段 位段的详细解释 位段其实也是一种结构体的类型 1.位段的成员是 int ,short int unsigned int , signed int , short , char 类型 2.位段的成员名后有一个冒号和一个数字 看一个例子&#xff1a; st…

通过静态LSP、LDP LSP、MPLS TE三种方式实现总部与分支的互通

一、静态LSP 特点&#xff1a;类似静态路由&#xff0c;简单易用&#xff0c;手动建立lsp&#xff0c;定制转发路径&#xff0c;无需控制报文&#xff0c;资源消耗少。 缺点&#xff1a;不适合大型复杂拓扑&#xff0c;不能根据网络变化而动态调整&#xff0c;需要管理员手动调…

【jprofiler应用-oom原因定位】

1.安装jprofiler jprofiler_windows-x64_11_0_2.exe 2.使用KeyGen.exe生成注册码然后输入 3.idea中安装jprofiler插件 File-->Setting-->Plugins 搜索jprofiler插件然后安装 4.以一个内存溢出的程序为例子进行分析(一直分配内存&#xff0c;List容器引用着Student导致…

医疗产品设计的新趋势

随着个人健康和医疗数据技术的发展&#xff0c;消费者可以选择更多的方法来跟踪和管理他们的健康状况&#xff0c;因此医疗产品开始转向更多的健康预防领域。医疗器械设计公司认为&#xff0c;随着医疗产品设计从医疗产品转向家庭&#xff0c;医疗产品的设计需要考虑更多的新问…

【HTML+CSS+JavaScript】实现简单网页版的飞机大战

文章目录【HTMLCSSJavaScript】实现简单网页版的飞机大战一. HTML部分代码二. CSS部分代码三. JavaScript部分代码四. 完整的代码和图片获取【HTMLCSSJavaScript】实现简单网页版的飞机大战 本文分享的是键盘版飞机大战的代码&#xff0c;且文章末尾有惊喜。 效果图&#xff1a…

前端食堂技术周刊第 64 期:Node.js 19、Interop 2022、SvelteKit 1.0、2022 Web 性能回顾、最流行的 Node.js

美味值&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f; 口味&#xff1a;冰糖雪梨 食堂技术周刊仓库地址&#xff1a;https://github.com/Geekhyt/weekly 本期摘要 Node.js 19 的新特性Interop 2022 年终更新SvelteKit 1.02022 Web 性能回…

Python爬虫学习第十二天---scrapy学习

Python爬虫学习第十二天—scrapy学习 一、scrapy的概念和流程 1、scrapy概念 Scrapy是一个Python编写的开源网络爬虫框架&#xff0c;它是一个被设计用于爬取网络数据、提取结构性数据的框架。Scrapy文档地址&#xff1a;http://scrapy-chs.readthedocs.io/zh_CN/1.0/intro/…

采用抓包的方式逆向获得谷歌翻译的API

文章目录最开始的尝试2022.12.26谷歌翻译API相关信息发送网址提交的数据不过不出意外的失败了实验去掉参数去掉Headers代码对返回结果进行解析完整代码最开始的尝试 谷歌的翻译API老是发生变化&#xff0c;我们需要自己动手来找到谷歌的翻译API&#xff0c;这样才是最稳妥的解决…

个人博客系统(前后端分离)

努力经营当下&#xff0c;直至未来明朗&#xff01; 文章目录一、项目简介二、项目效果三、项目实现1. 软件开发的基本流程2. 博客系统 需求分析3. 博客系统 概要设计4. 创建maven项目5. 编写数据库操作的代码四、项目代码总结普通小孩也要热爱生活&#xff01; 一、项目简介 …

Mac 音频转换器推荐 DRmare Audio Converter、Audi Free Auditor

Mac 音频转换器推荐 DRmare Audio Converter、Audi Free Auditor 给大家推荐两款 Mac 上的音频转换器&#xff0c;这两款转换器都可以转换苹果音乐&#xff0c;iTunes歌曲或者一些常规的音轨到MP3, FLAC, WAV, M4A, AAC格式等等&#xff0c;转换后我们就可以在所有的设备和播放…

stm32f407VET6 系统学习 day06 窗口看门狗, IIC 通信协议

1.独立看门狗&#xff0c;与窗口看门狗的差别 1. 差别1 &#xff1a; 窗口看门狗&#xff0c; 有上限 0x7F&#xff0c; 有下限 0x40 &#xff0c;&#xff0c; 独立看门狗只有下限 0 2. 差别2&#xff1a; 时钟源不同&#xff0c; 独立看门狗&#xff1a;LSI 窗口…

【iMessage苹果推群发】苹果相册推它由pushchatkey.pem和pushchatcert.pem作为单独的文件使用

推荐内容IMESSGAE相关 作者推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者推荐内容3.日历推 *** 点击即可查看作者要求内容信息作者推荐…

cut与分层抽样

个人觉得&#xff0c; 把分层抽样称为“分类采样”会更贴切一些。通常最基本的采样手段是&#xff1a;随机抽样&#xff0c;但是在很多场景下&#xff0c;随机抽样是有问题的&#xff0c;举一个简单的例子&#xff1a;如果现在要发起一个啤酒品牌知名度的调查问卷&#xff0c;我…

Improved Unsupervised Lexical Simplification with Pretrained Encoders 论文精读

Improved Unsupervised Lexical Simplification with Pretrained Encoders 论文精读InformationAbstract1 Introduction2 System Description2.1 Simplification Candidate Generation2.2 Substitution Ranking2.3 Obtaining Equivalence Scores3 End-to-end System Performanc…

好书推荐《C++17 in Detail》

无意中发现作者的博客&#xff08;https://www.cppstories.com/&#xff09;和这本书。这本书算是对C17新增特性较为全面的介绍&#xff0c;而且从实战出发&#xff0c;不流于语法细枝末节&#xff0c;简洁清晰&#xff0c;可以作为Scott Meyers那本非著名的《Effective Modern…

2022环境电器年度行业分析报告:洗地机同比增长357%,扫地机器人销量197万+

在当前的大环境下&#xff0c;人们的消费观念不断变化&#xff0c;健康因素在购买决策中的比重逐渐增大&#xff0c;因此&#xff0c;与此挂钩的环境电器行业也迎来发展变化。 在这里&#xff0c;鲸参谋也综合了京东平台环境电器中一些重点类目的销售数据&#xff0c;主要包括吸…

Krita像素画教程

Krita Windows 上一款自由开源的绘画软件 Krita 是一款自由开源的免费绘画软件&#xff0c;使用 GPL 许可证发布。它的功能齐全&#xff0c;能胜任从起草、勾线、上色到最终调整的所有绘画流程&#xff0c;可以绘制概念草图、插画、漫画、动画、接景和 3D 贴图&#xff0c;支持…

云服务器部署内网穿透映射本地服务

项目开发时需要和前端联调&#xff0c;考虑使用内网穿透避免每次上传服务部署的过程 下载frp &#xff08;开源内网穿透、反向代理工具&#xff09; https://github.com/fatedier/frp/releases/上传云服务器并解压&#xff08;使用xftp等工具上传&#xff09; tar -zxvf frp_0…

尚硅谷JavaWeb教程

1、Servlet Server Applet 全称为&#xff1a;Java Servlet是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据&#xff0c;生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口&#xff0c;广义的Servlet是指任何实现了这个Servlet接口的类。 1.1、Ser…

李沐精读论文:DETR End to End Object Detection with Transformers

论文&#xff1a; End-to-End Object Detection with Transformers 代码&#xff1a;官方代码 Deformable DETR&#xff1a;论文 代码 视频&#xff1a;DETR 论文精读【论文精读】_哔哩哔哩_bilibili 本文参考&#xff1a; 山上的小酒馆的博客-CSDN博客 端到端目标检测DETR…