题目地址:
https://www.luogu.com.cn/problem/P3811
题目描述:
给定
n
,
p
n,p
n,p求
1
∼
n
1\sim n
1∼n中所有整数在模
p
p
p意义下的乘法逆元。这里
a
a
a模
p
p
p的乘法逆元定义为
a
x
≡
1
(
m
o
d
p
)
ax\equiv1\pmod p
ax≡1(modp)的解。
输入格式:
一行两个正整数
n
,
p
n,p
n,p。
输出格式:
输出
n
n
n行,第
i
i
i行表示
i
i
i在模
p
p
p下的乘法逆元。
数据范围:
1
≤
n
≤
3
×
1
0
6
,
n
<
p
<
20000528
1 \leq n \leq 3 \times 10 ^ 6, n < p < 20000528
1≤n≤3×106,n<p<20000528
输入保证
p
p
p为质数。
单个数求模某个素数的逆元可以用费马小定理转化为快速幂来求。本题要求 1 ∼ n 1\sim n 1∼n每个数的模 p p p逆元,这么做时间是 O ( n log n ) O(n\log n) O(nlogn)会超时,从而需要别的办法。设 f [ i ] f[i] f[i]为 i i i模 p p p的逆元,则 f [ 1 ] = 1 f[1]=1 f[1]=1。考虑 f [ x ] , x > 1 f[x],x>1 f[x],x>1,设 p = k x + b , k = ⌊ p x ⌋ p=kx+b,k=\lfloor \frac{p}{x}\rfloor p=kx+b,k=⌊xp⌋,那么 k x + b ≡ 0 ( m o d p ) kx+b\equiv 0(\mod p) kx+b≡0(modp)由于 p p p是素数,所以 k b − 1 + x − 1 ≡ 0 ( m o d p ) x − 1 ≡ − ⌊ p x ⌋ b − 1 ≡ ( p − ⌊ p x ⌋ ) ( p m o d x ) − 1 ( m o d p ) kb^{-1}+x^{-1}\equiv 0(\mod p)\\x^{-1}\equiv -\lfloor \frac{p}{x}\rfloor b^{-1}\equiv (p-\lfloor\frac{p}{x}\rfloor) (p\mod x)^{-1} (\mod p) kb−1+x−1≡0(modp)x−1≡−⌊xp⌋b−1≡(p−⌊xp⌋)(pmodx)−1(modp)而 p m o d x < x p\mod x<x pmodx<x,所以有 f [ x ] = ( p − ⌊ p x ⌋ ) f [ p m o d x ] f[x]=(p-\lfloor\frac{p}{x}\rfloor)f[p\mod x] f[x]=(p−⌊xp⌋)f[pmodx]从而可以递推。代码如下:
#include <iostream>
using namespace std;
const int N = 3e6 + 10;
long inv[N];
int main() {
int n, p;
scanf("%d%d", &n, &p);
inv[1] = 1;
puts("1");
for (int i = 2; i <= n; i++)
printf("%ld\n", inv[i] = (long)p - (p / i) * inv[p % i] % p);
}
时空复杂度 O ( n ) O(n) O(n)。