古典叙事 · 技术札记

序章

山河有卷
人间有声

写代码,也写长风、旧城与未熄的灯。
愿每一篇随笔,都有自己的山水与回声。
阅览随笔

线性求逆元

P3811 【模板】模意义下的乘法逆元

题目背景

这是一道模板题。

题目描述

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

\(a\)\(p\) 的乘法逆元定义为 \(ax\equiv1\pmod p\) 的解。

输入格式

一行两个正整数 \(n,p\)

输出格式

输出 \(n\) 行,其中第 \(i\) 行表示 \(i\) 在模 \(p\) 下的乘法逆元。

输入输出样例 #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 $ 为质数。
线性求逆元算法可以在 \(O(n)\) 的时间复杂度内,求出 \(1 \sim n\) 中所有数在模 \(p\) 意义下的乘法逆元(前提是 \(p\) 为质数)。这在算法竞赛中处理大量组合数取模等问题时非常常用。核心公式推导要求 \(i\) 在模 \(p\) 意义下的逆元 \(inv[i]\)。首先,将 \(p\) 表示为带余除法的形式:$$p = k \cdot i + r$$其中商 \(k = \lfloor p/i \rfloor\),余数 \(r = p \bmod i\)。将上式放到模 \(p\) 的意义下,显然有:$$k \cdot i + r \equiv 0 \pmod p$$等式两边同时乘上 \(i^{-1} \cdot r^{-1}\)(即 \(inv[i] \cdot inv[r]\)):$$k \cdot r^{-1} + i^{-1} \equiv 0 \pmod p$$移项得到 \(i^{-1}\):$$i^{-1} \equiv -k \cdot r^{-1} \pmod p$$将 \(k\)\(r\) 替换回原来的表达式:$$inv[i] \equiv -\lfloor p/i \rfloor \cdot inv[p \bmod i] \pmod p$$代码实现优化:在 C++ 中,直接使用负数取模可能会得到负数结果。为了保证结果为正数,通常将 \(-\lfloor p/i \rfloor\) 替换为 \((p - \lfloor p/i \rfloor)\),即:$$inv[i] = (p - \lfloor p/i \rfloor) \cdot inv[p \bmod i] \bmod p$$

通过代码

#include <iostream>
#include <algorithm>
using namespace std;
using i64 = long long;
i64 t;
i64 a[3000005],b[3000005];
int main() {
	ios_base::sync_with_stdio(false);
    	cin.tie(nullptr);
		cout.tie(nullptr);
	i64 p;
	cin >> t>>p;
	a[1] = 1;
	for (i64 i = 2; i <= t; i++) {
		a[i] = (p - p / i) * a[p % i] % p;
	}
	for (i64 i = 1; i <= t; i++) {
		cout << a[i] <<'\n';
	}

}
posted @ 2026-04-14 17:06  Morphis‘  阅读(9)  评论(0)    收藏  举报

特别策划 · CINEMATIC NOTES

风沙与孤骑

风起塞外,
胜负在刀剑之前。

“把复杂拆成秩序,把未知写成答案。”
Morphis · 山河一卷 愿你从这里出发,仍能听见山风。 影像:farfarSébastien Goldberg / Unsplash