模反元素 (Modular Multiplicative Inverse)
模反元素 (Modular Multiplicative Inverse)
模板: Luogu P3811
求 到 每个数模 意义下最小正整数乘法逆元
, ,
概念
模反元素, 又称模逆元, 简称逆元, 其定义是在取模意义下的倒数
则称 是 模 意义下的逆元.
模 意义下的逆元存在当且仅当 , 互质, 接下来给出证明.
Exgcd
根据定义, 整理式子
根据最大公因数的定义, 是式子 最小的正值. 如果 , 那么必须满足 , 即两数互质.
可以用 exgcd
快速算出使得 的 , 的一组解, 通过使 对 的取模, 可以常数时间利用 求出最小的正整数解.
当然, 由于求 个数的逆元, 一次操作复杂度 , 最后是会超时的, 第一次提交总时间是 , 在我在细节上压榨过常数之后, 下面这份代码的时间来到了 .
inline void Exgcd(int a, int b, int &x, int &y) {
if(!b) {
x = 1;
y = 0;
}
else {
Exgcd(b, a % b, y, x);
y -= (a / b) * x;
}
}
signed main() {
n = RD();
p = RD();
for (register int i(1); i <= n; ++i) {
Exgcd(p, i, A, B);
B %= p;
B += p;
B %= p;
printf("%d\n", B);
}
return Wild_Donkey;
}
接下来, 分析代码, 发现递归是可以优化的, 于是改成循环, 优化到
inline void Exgcd(int a, int b, int &x, int &y) {
int tmp;
Cnt = 0;
while(b) {
a_b[++Cnt] = a / b;
tmp = a;
a = b;
b = tmp % b;
}
x = 1;
y = 0;
for (register unsigned j(Cnt); j >= 1; --j) {
tmp = x;
x = y;
y = tmp - a_b[j] * x;
}
}
然后发现还有好多时间浪费到了输出上, 从网上嫖了个 fwrite
, 并且进一步在细节上压榨 (如, 内层循环用 short
类型的控制器), 优化到 .
signed main() {
n = RD();
p = RD();
for (register unsigned i(1); i <= n; ++i) {
C = p;
D = i;
Cnt = 0;
while(D) {
a_b[++Cnt] = C / D;
Tmp = C;
C = D;
D = Tmp % D;
}
A = 1;
B = 0;
for (register short j(Cnt); j >= 1; --j) {
Tmp = A;
A = B;
B = Tmp - a_b[j] * A;
}
B %= p;
B += p;
B %= p;
write(B);
}
fwrite(_d,1,_p-_d,stdout);
return Wild_Donkey;
}
最后发现 Tmp
是 unsigned
, 其它的变量是 int
, 强转浪费时间了, 于是都改成 int
之后, 直接一波优化到 .
线性递推
用 表示 , 设 ,
如果用 表示 模 意义下的逆元, 则式子除以 得
移项, 由于所求的 , 得到表达式
可以递推求解
由于 , 所以 , 已经求出, 而 , 可以直接求, 所以可以线性时间求 到 , 下面这份代码只用了
signed main() {
n = RD();
p = RD();
a[1] = 1;
write(a[1]);
for (register unsigned i(2); i <= n; ++i) {
a[i] = ((long long)a[p % i] * (p - p / i)) % p;
write(a[i]);
}
fwrite(_d,1,_p-_d,stdout);
return Wild_Donkey;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)