当前位置: 首页 > news >正文

洛谷 P3811 【模板】模意义下的乘法逆元-普及/提高-

题目背景

这是一道模板题

题目描述

给定 n,pn,pn,p1∼n1\sim n1n 中所有整数在模 ppp 意义下的乘法逆元。

这里 aaappp 的乘法逆元定义为 ax≡1(modp)ax\equiv1\pmod pax1(modp) 的解。

输入格式

一行两个正整数 n,pn,pn,p

输出格式

输出 nnn 行,第 iii 行表示 iii 在模 ppp 下的乘法逆元。

输入输出样例 #1

输入 #1

10 13

输出 #1

1
7
9
10
8
11
2
5
3
4

说明/提示

$ 1 \leq n \leq 3 \times 10 ^ 6,,n < p < 20000528 $。

输入保证 $ p $ 为质数。

solution

思路: 求乘法逆元的方式有很多中

  • 1 可以用拓展欧几里得算法直接求解方程 ax=1 mod p
  • 2 可以用费马小定理 a^p-1=1 即 a^p-2 即为a的逆元
  • 3 前两个算法对于求单个逆元都是比较快的,但是如果要求 [1, n] 所有数的逆元,可以用递推公式实现线性时间复杂度
    例如求 i 的逆元 p = ki + r
    • 3.1 ki + r = 0 mod p
      两边乘以 i^-1 * r^-1 得到
    • 3.2 kr^-1 + i^-1 = 0 mod p 即 i^-1 = -kr^-1 mod
      其中 r 必然比 i 小,所以从小到大递推必然可以
      易得 1 * 1 = 1 mod p
  • 4 可以用阶乘逆元
    • 用 f[n] 表示 n! 的逆元, 则
      • (1) f[n] * n! = 1
      • (2) f[n-1] * (n-1)! = 1
    • 将(2)代入(1)中, 即 f[n] * n = f[n-1]
      • n^-1 = f[n] * (n-1)!
        具体做法是先求 g[i] = i!, 然后求 f[n] = g[n]^-1 (可以用快速幂), 然后逆着推求 f[i]
        然后 i^-1 = f[n] * g[n-1]
        这个也是线性的,但是比较麻烦,其主要用于求阶乘的逆元

代码

#include "cstring"
#include "string"
#include "algorithm"
#include "iostream"
#include "vector"
#include "unordered_set"
#include "unordered_map"
#include "bitset"
#include "queue"
#include "set"using namespace std;/**  思路:求乘法逆元的方式有很多中*  1 可以用拓展欧几里得算法直接求解方程 ax=1 mod p*  2 可以用费马小定理 a^p-1=1 即 a^p-2 即为a的逆元*  3 前两个算法对于求单个逆元都是比较快的,但是如果要求 [1, n] 所有数的逆元,可以用递推公式实现线性*      例如求 i 的逆元 p = ki + r*      3.1  ki + r = 0 mod p*      两边乘以 i^-1 * r^-1 得到*      3.2 k*r^-1 + i^-1 = 0 mod p  即  i^-1 = -k*r^-1 mod p*      其中 r必然比 i 小,所以从小到大递推必然可以*      易得 1 * 1 = 1 mod p*  4 可以用阶乘逆元*      用 f[n] 表示 n! 的逆元, 则*          (1) f[n] * n! = 1*          (2) f[n-1] * (n-1)! = 1*      将(2)代入(1)中, 即 f[n] * n = f[n-1]*      n^-1 = f[n] * (n-1)!*      具体做法是先求 g[i] = i!, 然后求 f[n] = g[n]^-1 (可以用快速幂), 然后逆推求 f[i]*      然后 i^-1 = f[n] * g[n-1]*      这个也是线性的,但是比较麻烦,其主要用于求阶乘的逆元*/const int N = 3e6 + 5, M = 2e6, INF = 1e9, MOD = 998244353;
typedef long long ll;int n, inv[N], p;int main() {scanf("%d%d", &n, &p);inv[1] = 1;printf("%d\n", 1);for (int i = 2; i <= n; i++) {//i^-1 = -k*r^-1 mod pinv[i] = p - 1ll * p / i * inv[p % i] % p;printf("%d\n", inv[i]);}return 0;}

结果

在这里插入图片描述

http://www.dtcms.com/a/346262.html

相关文章:

  • html基本元素
  • 嵌入式第三十五天(网络编程(UDP))
  • 特大桥施工绳断 7 人亡:索力实时监测预警机制亟待完善
  • STM32F1 EXTI介绍及应用
  • tiktok滑块反爬分析verifyV2
  • Linux设备模型技术路线图
  • B树,B+树,B*树
  • Codeforces Round 1043 (Div. 3)
  • set_case_analysis应用举例
  • 技术里常说 没有银弹
  • 纳米软件自动化测试平台ATECLOUD产品手册之一——系统介绍
  • 声网如何让AI理解画面、情绪和你说的话
  • 【资源分享】(影视相关)
  • Claude Code 三类.md文件
  • Java 18 新特性及具体应用
  • WMS选型攻略:钱该省在哪?部署怎么定?
  • openEuler系统安装Ascend Docker Runtime的方法
  • open webui源码分析7—过滤器
  • 劳务工队:建筑工程的基石力量,行业生态的多元拼图
  • RKLLM 模型转换从0开始
  • 测试工程师面试题 + 简短答案
  • Scala面试题及详细答案100道(1-10)-- 基础语法与数据类型
  • 如何理解AP服务发现协议中“如果某项服务需要被配置为可通过多个不同的网络接口进行访问,则应为每个网络接口使用一个独立的客户端服务实例”?
  • 异步开发相关概念
  • BurpSuite 1.4.07.jar 怎么使用?详细安装和抓包教程(附安装包下载)
  • 12.从零开始写LINUX内核--控制台初始化
  • 商密保卫战:保密性认定的司法迷局与破局之道
  • 记录一下面试题:找字符串中第一次出现1次的字符
  • Kubernetes配置与密钥管理及存储体系实战指南
  • Adobe Illustrator默认键盘快捷键