数论同余学习笔记 Part 2
逆元
准确地说,这里讲的是模意义下的乘法逆元。
定义:如果有同余方程 \(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)\),单次求逆元似乎没有更优的做法了
但要算多个逆元时有一些技巧可以做到线性
给定 \(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\),则
\]
为得到 \(x^{-1}\),将两边同除以 \(x\)
\]
整理一下
\]
代入 \(a=p/x,b=p\%x\)
\]
即得递推式。
核心代码:
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)\)。在一些组合计数的题中会更自然地用到。
然后是第二道板子题
给定 \(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的更多相关文章
- 五一DAY1数论学习笔记
by ruanxingzhi 整除性 如果a能把b除尽,也就是没有余数,则我们称a整除b,亦称b被a整除.(不是除以,是整除!!) 记作:\(a|b\) |这个竖杠就是整除符号 整除的性质 自反性 对 ...
- 数论算法 剩余系相关 学习笔记 (基础回顾,(ex)CRT,(ex)lucas,(ex)BSGS,原根与指标入门,高次剩余,Miller_Rabin+Pollard_Rho)
注:转载本文须标明出处. 原文链接https://www.cnblogs.com/zhouzhendong/p/Number-theory.html 数论算法 剩余系相关 学习笔记 (基础回顾,(ex ...
- [学习笔记]NTT——快速数论变换
先要学会FFT[学习笔记]FFT——快速傅里叶变换 一.简介 FFT会爆精度.而且浮点数相乘常数比取模还大. 然后NTT横空出世了 虽然单位根是个好东西.但是,我们还有更好的东西 我们先选择一个模数, ...
- [学习笔记] 多项式与快速傅里叶变换(FFT)基础
引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积, 而代码量却非常小. 博主一年半前曾经因COGS的一 ...
- OI数学 简单学习笔记
基本上只是整理了一下框架,具体的学习给出了个人认为比较好的博客的链接. PART1 数论部分 最大公约数 对于正整数x,y,最大的能同时整除它们的数称为最大公约数 常用的:\(lcm(x,y)=xy\ ...
- 「学习笔记」FFT 之优化——NTT
目录 「学习笔记」FFT 之优化--NTT 前言 引入 快速数论变换--NTT 一些引申问题及解决方法 三模数 NTT 拆系数 FFT (MTT) 「学习笔记」FFT 之优化--NTT 前言 \(NT ...
- 快速傅里叶变换(FFT)学习笔记(其二)(NTT)
再探快速傅里叶变换(FFT)学习笔记(其二)(NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其二)(NTT) 写在前面 一些约定 前置知识 同余类和剩余系 欧拉定理 阶 原根 求原根 NTT ...
- 初等数论学习笔记 III:数论函数与筛法
初等数论学习笔记 I:同余相关. 初等数论学习笔记 II:分解质因数. 1. 数论函数 本篇笔记所有内容均与数论函数相关.因此充分了解各种数论函数的名称,定义,符号和性质是必要的. 1.1 相关定义 ...
- swift学习笔记1——基础部分
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
随机推荐
- bugku的一道XFF转发代理服务器题 “本地服务器”
X-Forwarded-For requests包内构造方式: X-Forwarded-For: client1, proxy1, proxy2
- 解决ubuntu突然无法联网问题
一.问题描述 今天使用笔记本远程办公的时候,突然电脑无法联网了,使用chrome浏览器访问网页出现如下错误 This site can't be reachedwww.baidu.com's serv ...
- Adversarial Detection methods
目录 Kernel Density (KD) Local Intrinsic Dimensionality (LID) Gaussian Discriminant Analysis (GDA) Gau ...
- pytest之 fixture 实现机制
一.相同测试数据存放优化 在讲 fixture 实现机制之前,插入一段内容 上次有个小伙伴问我说,类似下面的用例代码情况,每条测试用例的数据都一样的,我们可以怎么进行优化吗? 当然是可以的 其实我们可 ...
- MySQL数据操作与查询笔记 • 【第7章 连接查询】
全部章节 >>>> 本章目录 7.1 内连接查询 7.1.1 交叉连接(笛卡尔积) 7.1.2 内连接查询概要 7.1.3 内连接案例 7.1.4 自然连接 7.2 多表连 ...
- Maven常用参数说明
缩写 全名 说明 -h --help 显示帮助信息 -am --also-make 构建指定模块,同时构建指定模块依赖的其他模块 -amd --also-make-dependents 构建指定模块, ...
- Ranger开源流水线docker化实践案例
1.背景 开发部门决定在Apache Ranger开源社区贡献代码,目标是个人国内排名Top1,世界排名Top2,并且在已经成为Ranger项目的Committer情况下,争取成为Ranger项目的P ...
- CSS基础 BFC的使用方法
BFC的作用和创建1.html标签是BFC盒子2.浮动元素是BFC盒子3.行内块元素是BFC盒子4.overflow属性值不为visible,如:auto.hidden...作用:1.清除浮动: 2. ...
- 字符串的展开expand
A. 字符串的展开(expand.cpp) 内存限制:64 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 在初赛普及组的"阅读程序写结果&qu ...
- js实现工具函数中groupBy数据分组
数据 this.tableData = [ {id: 1, name: '测试', number: 1, price: 0}, {id: 2, name: '测试', number: 1, price ...