逆元

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

定义:如果有同余方程 \(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. Codeforces 777B:Game of Credit Cards(贪心)

    After the fourth season Sherlock and Moriary have realized the whole foolishness of the battle betwe ...

  2. Codeforces 1073D:Berland Fair(模拟)

    time limit per test: 2 secondsmemory limit per test: 256 megabytesinput: standard inputoutput: stand ...

  3. Java生成随机数的4种方式

    Random Random 类诞生于 JDK 1.0,它产生的随机数是伪随机数,也就是有规则的随机数.Random 使用的随机算法为 linear congruential pseudorandom ...

  4. Java基础寒假作业-简易计算器

    需求: 使用Java编写计算器的控制台程序,完成简单的加减乘除运算.实现以下功能: 1.运算选择 请用户选择一个算法(1.加法 2.减法 3.乘法 4.除法 5.关闭计算器) 2.计算 a)加法:实现 ...

  5. python uwsgi 配置

    启动:uwsgi --ini xxx.ini 重启:uwsgi --reload xxx.pid 停止:uwsgi --stop xxx.pid ini 文件 [uwsgi] chdir = /vag ...

  6. Oracle导出导入dmp文件(exp.imp命令行)

    1.说明 使用Oracle命令行导出导入dmp文件, 从而在两个数据库之间快速转移数据, 也可以用来作为数据库的备份, 将来可以快速恢复数据. 命令:导出exp.导入imp 步骤: 使用Oracle的 ...

  7. hisql 高级功能数据检测将错误数据拦截在系统外 一

    hisql github源码下载 git clone https://github.com/tansar/HiSql.git 在设计第二范式数据库时经常会把可能重复的数据单独做一种表关联,但是在写入表 ...

  8. hive 之 将excel数据导入hive中 : excel 转 txt

    一.需求: 1.客户每月上传固定格式的excel文件到指定目录.每月上传的文件名只有结尾月份不同,如: 10月文件名:  zhongdiangedan202010.xlsx  , 11月文件名: zh ...

  9. VMware_win10能ping通虚拟机ip,虚拟机ping不通win10ip的解决方法

    一.虚拟机设置为桥接模式 二.修改虚拟机linux的ip 查看win10的ip和网关 使用ifconfig查看网卡名,并在 /etc/sysconfig/network-scripts/目录修改对应的 ...

  10. git 忽略本地文件的修改

    项目开发过程中,会遇到本地配置文件每个开发人员不同的情况,但如果遇到类似数据库配置这种最终需要加入 git 版本控制的配置,则会陷入两难境地.要么不跟踪,要么有人提交后其他人同步下来必须手动修改,非常 ...