《洛谷深入浅出进阶篇》模意义下的乘法逆元+洛谷P3811

什么是乘法逆元?

算数意义上的乘法逆元指的是倒数,即:a*(1/a)=1


所以 1/a 是 a在算数意义下的乘法逆元,或者可以说二者互为逆元。
这有什么用呢?


除以a就等于乘上a的乘法逆元,乘以a等于除以a的乘法逆元。

那么我们回到我们要介绍的新的乘法逆元:模意义上的乘法逆元。(使用条件,当一个正整数做分母的时候)

例如我们要求(x+y)*(x-y)/2 mod p

很显然,对于分子,我们可以直接用模的性质
(x+y)*(x-y)modp = 【(x+y)%p *(x-y)%p】%p


但是,这样的方法只对加减乘有效。

除法的话,由于整除向下取整的原因,我们无法直接使用。这时候就要用到逆元,来代替除法,因为除以一个数取模,等于乘上它在模意义上的逆元,后取模。

ok,那么什么是模意义上的乘法逆元呢?


  给出定义: a*x = 1(mod)p,也就是a*x对p取模为1的时候,x就是a 的逆元,所以,当除以a的时候就相当于是乘上a的逆元x。(注意,模只对整数时有意义的,所以我们的变量都应该是整数)

那么我们知道了模意义上的乘法逆元,应该怎么求它的乘法逆元呢?
就可以用到三种方法:扩展欧几里得算法,费马小定理,线性递推。

扩展欧几里得算法:

a*x=1 (mod)p
这个式子可以展开写成:(扩展欧几里得相关文章连接:
《洛谷深入浅出进阶篇》 欧几里得算法,裴蜀定理,拓展欧几里得算法————洛谷P1516 青蛙的约会-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/louisdlee/article/details/134751119?spm=1001.2014.3001.5502
a*x+p*y=1
也就是求x,y的不定方程。
我们由裴蜀定理可知:这个方程只有gcd(a,p)=1的时候才有解,所以,gcd=1是求逆元的前提条件。

然后我们直接套exgcd(a,p,x,y)即可
虽然求出来的是a的一个逆元,但是我们由拓展欧几里得可以求出通式,x=x1+k*lcm(a,p)/a   (k可以取任意整数)

只要不断+模数p就可以求出最小正整数解

2,费马小定理:如果p是质数,且gcd(a,p)=1,a^(p-2)是a的一个乘法逆元。


那么如何求a^(p-2)?
我们可以用到快速幂的方法,

s=1,t=p-2   y=a
while(t!=0){
     if(p&1==1)s=s*y
     y*=y;
     t/=2;
}

线性递推求逆元


假如给你1~n个数,让你求所有整数在模p意义下的乘法逆元。你应该怎么办?(n<=1e6)

如果你每次都用exgcd或者费马小定理+快速幂这题是肯定是会超时的,所以我们只能用线性优化了。

只能使用递推的方式来解决这道题

那么我们必须找到递推的式子

假设 inv(i)是i在模意义下的逆元(记住板子即可)

p=i*q+r,其中q=【p/i】(整除),r=p%i。
第一个式子:p=i*q+r

在模意义下可以得到这样的式子:
 i*q+r == 0 (mod p)

变形为: i ==  -r/q  (mod p)

等价于:i== -r * inv(q)  (mod p)

两边取倒数:(整数的倒数来表示逆元函数)

1/i == -1/r   *   q

inv(i) == -inv(r)*q == -inv(r)*【p/i】;

因为 r=p%i,所以r是一定小于当前的i的,怎么求inv(r)

由于我们是递推求逆元,当求到i时,说明i-1,i-2,......1 都求出来了。

所以我们只要注意边界 inv(1) =1即可

但是还是有一个问题,就是,这样求出来的逆元,有些是负数的,如果我们要求逆元的最小正整数应该怎么办?
那也好办,不断在其后面加上p就可以了,当逆元大于0,退出循环。

上代码:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<cctype>
#include<map>
#include<set>
#include<queue>
#include<numeric>
#include<iomanip>
using namespace std;
typedef long long LL;
const int N = 3e6 + 7;
LL inv[N];
int main()
{
	LL n,p;
	cin >> n>>p;
	inv[1] = 1;
	for (int i = 2; i <= n; i++) {
		LL q = p / i;
		LL r = p % i;
		inv[i] = (-q * inv[r]%p)%p;
		while(inv[i]<0)inv[i]+=p;
	}
	for (int i = 1; i <= n; i++)cout << inv[i] << '\n';
}


 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JS不同运算符下的隐式类型转换

目录 运算符 逻辑运算符&#xff08;&&、||、!&#xff09;和 条件表达式&#xff08;if、三元表达式&#xff09; 逻辑运算符 条件表达式 算数运算符&#xff08;*、/、- %、&#xff09;和 关系运算符&#xff08;>、<、、!&#xff09; 算数运算符 关系…

solidity实现ERC721代币标准发布NFT

文章目录 1、非同质化货币&#xff08;NFT&#xff09;- 维基百科2、IERC1653、IERC7214、IERC721Receiver5、IERC721Metadata6、ERC7217、ERC721 NFT 的实现8、编译部署 1、非同质化货币&#xff08;NFT&#xff09;- 维基百科 非同质化代币&#xff08;英语&#xff1a;Non-F…

时间复杂度为O (nlogn)的排序算法

归并排序 归并排序遵循分治的思想&#xff1a;将原问题分解为几个规模较小但类似于原问题的子问题&#xff0c;递归地求解这些子问题&#xff0c;然后合并这些子问题的解来建立原问题的解&#xff0c;归并排序的步骤如下&#xff1a; 划分&#xff1a;分解待排序的 n 个元素的…

MySQL进阶部分

存储引擎 MySQL体系结构图&#xff1a; 连接层&#xff1a; 最上层是一些客户端连接服务&#xff0c;主要完成一些类似于连接处理 &#xff0c;授权认证及相关的安全方案。服务器也会为安全接入的每个用户端验证它所具有的操作权限。 服务层&#xff1a; 第二层架构主要完成大…

Visual Studio 2022+Python3.11实现C++调用python接口

大家好&#xff01;我是编码小哥&#xff0c;欢迎关注&#xff0c;持续分享更多实用的编程经验和开发技巧&#xff0c;共同进步。 查了一些资料&#xff0c;不是报这个错&#xff0c;就是报哪个错&#xff0c;没有找到和我安装的环境的一致的案例&#xff0c;于是将自己的摸索分…

贪心 55. 跳跃游戏 45.跳跃游戏 II

55. 跳跃游戏 题目&#xff1a; 给定非负数组&#xff0c;初始位置在数组第一格&#xff0c;数组值是可以选择的最大跳跃步数&#xff0c;判断能不能达到数组末尾。 示例 1: * 输入: [2,3,1,1,4] * 输出: true * 解释: 我们可以先跳 1 步&#xff0c;从位置 0 到达 位置 1,…

在Windows 11中,把iPhone照片和视频导出来又快又简单,无需第三方软件

如果你想将照片和视频从iPhone传输到Windows 11 PC&#xff0c;最快、最简单的方法是插入手机并执行自动导入。以下是操作方法。 如何将照片和视频从iPhone导入Windows 如果你用USB数据线将iPhone插入Windows PC&#xff0c;Windows 11可以像标准数码相机一样连接到它&#x…

JavaWeb 带条件的分页查询

最终效果图 注意&#xff1a;没有带条件的时候 默认的是第一页数据 条件是组合的 sql->sql的动态变换 注意第二次查询的时候回显问题 就是填完条件后显示完当页数据ok 但是我点击第二页的时候条件还存在着 此时ListSerevlet不仅要拿到页码 页容量 还要拿到三个条件参数 封装…

IDEA中的Postman!

Postman是大家最常用的API调试工具&#xff0c;那么有没有一种方法可以不用手动写入接口到Postman&#xff0c;即可进行接口调试操作&#xff1f;今天给大家推荐一款IDEA插件&#xff1a;Apipost Helper&#xff0c;写完代码就可以调试接口并一键生成接口文档&#xff01;而且还…

Excel 删除空白行

目录 一. 方式一: 筛选删除二. 方式二: 定位条件三. 方式三: 隐藏非空白行&#xff0c;删除空白行 一. 方式一: 筛选删除 选中空白行对应的列&#xff0c;按下Ctrl Shift L&#xff0c;给列添加过滤条件。过滤出空白行&#xff0c;然后删除即可。 二. 方式二: 定位条件 按下…

Excel 分列功能

一. 需求 ⏹有一段文本&#xff0c;文本一共有7列。这7列文本之间的分隔符不相同 有一个空格的有多个空格的有Tab的jmw_state 和 method 之间用 & 连接 现在要求&#xff0c;将这段文本粘贴到Excel中&#xff0c;进行分列。并且需要将 jmw_state 和 method 也进行分列 也…

使用求2个字符串最短编辑距离动态规划算法实现 git diff 算法 java 实现

测试类 MyDiffTest.java&#xff1a; import java.io.BufferedReader; import java.io.FileReader; import java.util.ArrayList; import java.util.List;public class MyDiffTest {private static String path "\\xxx\\";private static List<String> lines…

HBase整合Phoenix

文章目录 一、简介1、Phoenix定义2、Phoenix架构 二、安装Phoenix1、安装 三、Phoenix操作1、Phoenix 数据映射2、Phoenix Shell操作3、Phoenix JDBC操作3.1 胖客户端3.2 瘦客户端 四、Phoenix二级索引1、为什么需要二级索引2、全局索引&#xff08;global index&#xff09;3、…

基于SSM的网上手机销售系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

数据结构:堆的实现思路

我们之前写过堆的实现代码&#xff1a;数据结构&#xff1a;堆的实现-CSDN博客 这篇文章我们了解一下堆到底是如何实现的 1.堆向下调整算法 现在我们给出一个数组&#xff0c;逻辑上看做一颗完全二叉树。我们通过从根节点开始的向下调整算法可以把它调整成一个小堆 向下调…

小米秒享3--非小米电脑

小米妙享中心是小米最新推出的一款功能&#xff0c;能够为用户们提供更加舒适便利的操作体验。简单的说可以让你的笔记本和你的小米手机联动&#xff0c;比如你在手机的文档&#xff0c;连接小米共享后&#xff0c;可以通过电脑进行操作。 对于非小米电脑想要体验终版秒享AIOT…

自带灯效的气传导耳机,声音当然好听,哈氪聆光体验

现在市场上的蓝牙耳机种类繁多&#xff0c;入耳式的算是主流&#xff0c;但不太适合户外使用 &#xff0c;我平时出门健身、散步的时候&#xff0c;更喜欢用气传导耳机。气传导耳机通常采用挂耳式的设计&#xff0c;耳机不入耳&#xff0c;佩戴舒适度更好&#xff0c;而且稳定性…

viple模拟器使用(四):unity模拟器中实现两距离局部最优迷宫算法

名字解读 两距离&#xff1a;指的是左侧距离和右侧距离 局部最优&#xff1a;对当前状态来说最好的选择&#xff0c;至于整体能不能达到最优&#xff0c;是无法确定的。 从节点1到节点5&#xff0c;一共有3条路 第1条路线&#xff1a;1→2→4→5&#xff0c;对应的花销是&…

Linux dig指令的十三种用法

文章目录 dig指令有哪些作用dig 具体用法推荐阅读 dig指令有哪些作用 DIG命令(Domain Information Groper命令)是一个网络工具&#xff0c;具有基本的命令行接口&#xff0c;用于进行不同的DNS(域名系统)查询。您可以使用DIG命令: 诊断您的域名服务器。检查所有这些服务器或每…

OpenWrt作为旁路由(网关)配置

目录 背景前提条件环境操作步骤物理层连接设置与主路由同一网段禁用IPv6取消LAN接口桥接防火墙配置 背景 本文简介如何配置OpenWrt&#xff0c;使其作为旁路由&#xff08;网关&#xff09;运行。 旁路由大概有以下这几种工作方式&#xff1a; 主路由开DHCP&#xff0c;网关未…