逆元

准确地说,这里讲的是模意义下的乘法逆元。

定义:如果有同余方程 \(ax\equiv 1\pmod p\),则 \(x\) 称为 \(a\bmod p\) 的逆元,记作 \(a^{-1}\)。

作用是抵消乘法,即 \(x\cdot a\cdot a^{-1}\equiv x\pmod p\)

进一步可以得到 \(\frac xa\equiv x\times a^{-1}\pmod p\),这也是分数取模的计算方式

最通用的求法是 exgcd 。

\(ax\equiv 1\pmod p\) 等价于 \(ax+py=1(x,y\in\Z)\),可直接用 exgcd 求解。时间复杂度 \(O(\log p)\)。

这也表明当且仅当 \(\gcd(a,p)=1\) 时,\(a\bmod p\) 的逆元存在。

OI 中为了方便,往往选择一个大质数作为模数 \(p\),以保证在给定的数据范围内逆元始终存在。

下文仅讨论 \(p\) 为质数的情况,且默认其它数均小于 \(p\)

这里我们不加证明地引入费马小定理:若 \(p\) 为质数,\(a,p\) 互质,则 \(a^{p-1}\equiv 1\pmod p\)。

则 \(a^{-1}\equiv a^{p-2}\pmod p\),故直接用快速幂计算 \(a^{p-2}\bmod p\) 即得 \(a^{-1}\)。

时间复杂度是 \(O(\log p)\),单次求逆元似乎没有更优的做法了

但要算多个逆元时有一些技巧可以做到线性

洛谷P3811 【模板】乘法逆元

给定 \(n,p\),求 \(1\sim n\) 中所有整数在模 \(p\) 意义下的逆元。

\(1\le n\le 3\times10^6,n<p<20000528\),保证 \(p\) 为质数

有一个经典的线性递推求 \(1\sim n\) 逆元的方法。

比如我们当前求的是 \(x^{-1}\)。

设 \(p=ax+b\),则

\[ax\equiv -b\pmod p
\]

为得到 \(x^{-1}\),将两边同除以 \(x\)

\[a\equiv -b\cdot x^{-1}\pmod p
\]

整理一下

\[x^{-1}\equiv -a\cdot b^{-1}\pmod p
\]

代入 \(a=p/x,b=p\%x\)

\[x^{-1}\equiv -(p/x)\cdot (p\% x)^{-1}\pmod p
\]

即得递推式。

核心代码:

    inv[1]=1;
for (int i=2; i<=n; ++i)
inv[i]=1ll*(p-p/i)*inv[p%i]%p;

再讲一个有点奇怪的做法

所求即 \(inv(x)=x^{p-2}\)。注意到这是个积性函数。

于是可以用欧拉筛去筛它,当 \(x\) 为质数时用快速幂直接计算。

由于 \(1\sim n\) 的质数大约有 \(\ln n\) 个,这个做法的时间复杂度是 \(O\left(\dfrac{n\log p}{\ln n}+n\right)\),比 \(O(n)\) 略慢。

实际上这个技巧原本是 \(O\left(\dfrac{n\log k}{\ln n}+n\right)\) 计算 \(1^k\sim n^k\),这里令 \(k=p-2\) 强行套用了而已

也可以考虑预处理阶乘:

    fac[0]=1;
for (int i=1; i<=n; ++i) fac[i]=1ll*fac[i-1]*i%p;
inv[n]=power(fac[n],p-2,p); // 快速幂计算逆元
for (int i=n; i; --i) inv[i-1]=1ll*inv[i]*i%p;

其中 fac,inv 分别是阶乘及其逆元。显然 \(x^{-1}\equiv fac_x\cdot inv_{x-1}\pmod p\)。

时间复杂度 \(O(n)\)。在一些组合计数的题中会更自然地用到。

然后是第二道板子题

洛谷P5431 【模板】乘法逆元 2

给定 \(n\) 个正整数 \(a_i\),求它们在模 \(p\) 意义下的逆元。

为减少输出量,给定常数 \(k\),只需输出 \(\sum\limits_{i=1}^n\dfrac{k^i}{a_i}\)。

\(1\le n\le 5\times10^6,2\le k<p\le 10^9,1\le a_i<p\),保证 \(p\) 为质数

令 \(A\) 为所有数的积,\(pre_i\) 为前缀积,\(suf_i\) 为后缀积,则 \(a_i^{-1}=A^{-1}\cdot pre_{i-1}\cdot suf_{i+1}\)。

于是显然可以 \(O(n)\) 计算。

本质上是因为算除法(逆元)要一个 log ,而乘法是常数级,于是化除为乘减少计算量

感觉其实就是通分(?)

数论同余学习笔记 Part 2的更多相关文章

  1. 五一DAY1数论学习笔记

    by ruanxingzhi 整除性 如果a能把b除尽,也就是没有余数,则我们称a整除b,亦称b被a整除.(不是除以,是整除!!) 记作:\(a|b\) |这个竖杠就是整除符号 整除的性质 自反性 对 ...

  2. 数论算法 剩余系相关 学习笔记 (基础回顾,(ex)CRT,(ex)lucas,(ex)BSGS,原根与指标入门,高次剩余,Miller_Rabin+Pollard_Rho)

    注:转载本文须标明出处. 原文链接https://www.cnblogs.com/zhouzhendong/p/Number-theory.html 数论算法 剩余系相关 学习笔记 (基础回顾,(ex ...

  3. [学习笔记]NTT——快速数论变换

    先要学会FFT[学习笔记]FFT——快速傅里叶变换 一.简介 FFT会爆精度.而且浮点数相乘常数比取模还大. 然后NTT横空出世了 虽然单位根是个好东西.但是,我们还有更好的东西 我们先选择一个模数, ...

  4. [学习笔记] 多项式与快速傅里叶变换(FFT)基础

    引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积, 而代码量却非常小. 博主一年半前曾经因COGS的一 ...

  5. OI数学 简单学习笔记

    基本上只是整理了一下框架,具体的学习给出了个人认为比较好的博客的链接. PART1 数论部分 最大公约数 对于正整数x,y,最大的能同时整除它们的数称为最大公约数 常用的:\(lcm(x,y)=xy\ ...

  6. 「学习笔记」FFT 之优化——NTT

    目录 「学习笔记」FFT 之优化--NTT 前言 引入 快速数论变换--NTT 一些引申问题及解决方法 三模数 NTT 拆系数 FFT (MTT) 「学习笔记」FFT 之优化--NTT 前言 \(NT ...

  7. 快速傅里叶变换(FFT)学习笔记(其二)(NTT)

    再探快速傅里叶变换(FFT)学习笔记(其二)(NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其二)(NTT) 写在前面 一些约定 前置知识 同余类和剩余系 欧拉定理 阶 原根 求原根 NTT ...

  8. 初等数论学习笔记 III:数论函数与筛法

    初等数论学习笔记 I:同余相关. 初等数论学习笔记 II:分解质因数. 1. 数论函数 本篇笔记所有内容均与数论函数相关.因此充分了解各种数论函数的名称,定义,符号和性质是必要的. 1.1 相关定义 ...

  9. swift学习笔记1——基础部分

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

随机推荐

  1. bugku的一道XFF转发代理服务器题 “本地服务器”

    X-Forwarded-For requests包内构造方式: X-Forwarded-For: client1, proxy1, proxy2

  2. 解决ubuntu突然无法联网问题

    一.问题描述 今天使用笔记本远程办公的时候,突然电脑无法联网了,使用chrome浏览器访问网页出现如下错误 This site can't be reachedwww.baidu.com's serv ...

  3. Adversarial Detection methods

    目录 Kernel Density (KD) Local Intrinsic Dimensionality (LID) Gaussian Discriminant Analysis (GDA) Gau ...

  4. pytest之 fixture 实现机制

    一.相同测试数据存放优化 在讲 fixture 实现机制之前,插入一段内容 上次有个小伙伴问我说,类似下面的用例代码情况,每条测试用例的数据都一样的,我们可以怎么进行优化吗? 当然是可以的 其实我们可 ...

  5. MySQL数据操作与查询笔记 • 【第7章 连接查询】

    全部章节   >>>> 本章目录 7.1 内连接查询 7.1.1 交叉连接(笛卡尔积) 7.1.2 内连接查询概要 7.1.3 内连接案例 7.1.4 自然连接 7.2 多表连 ...

  6. Maven常用参数说明

    缩写 全名 说明 -h --help 显示帮助信息 -am --also-make 构建指定模块,同时构建指定模块依赖的其他模块 -amd --also-make-dependents 构建指定模块, ...

  7. Ranger开源流水线docker化实践案例

    1.背景 开发部门决定在Apache Ranger开源社区贡献代码,目标是个人国内排名Top1,世界排名Top2,并且在已经成为Ranger项目的Committer情况下,争取成为Ranger项目的P ...

  8. CSS基础 BFC的使用方法

    BFC的作用和创建1.html标签是BFC盒子2.浮动元素是BFC盒子3.行内块元素是BFC盒子4.overflow属性值不为visible,如:auto.hidden...作用:1.清除浮动: 2. ...

  9. 字符串的展开expand

    A. 字符串的展开(expand.cpp) 内存限制:64 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 在初赛普及组的"阅读程序写结果&qu ...

  10. js实现工具函数中groupBy数据分组

    数据 this.tableData = [ {id: 1, name: '测试', number: 1, price: 0}, {id: 2, name: '测试', number: 1, price ...