关于求 1~n 逆元

以下 p 为模数,x 为我们要求逆元的数。
最直接的是利用费马小定理,x1xp2(mod p)是,时间复杂度:O(nlog2(n))
这里有两个线性做法:

  1. p=ax+b,则 ax+b0(mod p),构造一下,两边同时除以 bx
    ab1+x10(mod p)=>x1(ab1)。令 dp[x]=x1,易知 a=p/x,b=p%x,则 dp[x]=(p/xdp[p%x])mod p
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <bitset>
#define uint unsigned int
#define LL long long
using namespace std;
const int MAXN = 3e6 + 5;
int n, p;
LL dp[MAXN];
// 令 p = ax+b, 则 ax+b=0(mod p)
// (ax+b)/(bx)=0(mod p)
// a*b^(-1)+x^(-1)=0 -> x^(-1)=-(p/x)/(p%x) -> dp[x]=-(p/x)*dp[p%x] 
int main() {
	scanf("%d%d", &n, &p); dp[1] = 1;
	for(int i = 2; i <= n; i ++) dp[i] = -(p / i * dp[p % i]), dp[i] = (dp[i] % p + p) % p;
	for(int i = 1; i <= n; i ++) printf("%lld\n", dp[i]);
	return 0;
} 
  1. 请注意 dp[x]=x1,发现这是一个完全积性函数,那么直接跑个埃筛维护即可,若它是质数直接跑费马小定理,否则直接转移,时间复杂度:O(n)+O(n/ln(n)log2(p)),约等于 O(n)
    p.s. 1n 的质数个数约有 n/ln(n) 个。
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <bitset>
#define uint unsigned int
#define LL long long
using namespace std;
const int MAXN = 3e6 + 5;
int inv[MAXN], prime[MAXN / 10], tot;
bitset <MAXN> vis;
int n, p;
int Quick_Pow(int x, int y) {
	int ans = 1;
	for(; y; y >>= 1) { if(y & 1) ans = (LL)ans * x % p; x = (LL)x * x % p; }
	return ans;
} 
void Prime() {
	inv[1] = 1;
	for(int i = 2; i <= n; i ++) {
		if(!vis[i]) prime[++ tot] = i, inv[i] = Quick_Pow(i, p - 2);
		for(int j = 1; j <= tot && i * prime[j] <= n; j ++) {
			vis[i * prime[j]] = 1; inv[i * prime[j]] = (LL)inv[i] * inv[prime[j]] % p;
			if(i % prime[j] == 0) break;
		}
	}
}
int main() {
	scanf("%d%d", &n, &p); Prime(); 
	for(int i = 1; i <= n; i ++) printf("%d\n", inv[i]);
	return 0;
}
posted @   Saintex  阅读(143)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示