乘法逆元进阶运用

线性求逆元

k=pi,r=pmodi

pik+r0(modp)

在两边分别乘上 i1j1

得到

(ik+r)(i1r1)0(modp)(k+ri1)r10(modp)kr1+i10(modp)i1kr1(modp)i1pi(pmodi)1(modp)

由于 0pmodi<i 故递推式成立。

乘法逆元的积性——离线逆元

我们说对于乘法逆元有:a1×b1(ab)1(modp)

证明: a×a11(modp)b×b11(modp)

将两式相乘,a×b×a1×b11(modp),显然 a1×b1ab 的逆元。

于是乘法逆元积性得证,我们可以用它解决一些问题。

例如

前缀积。设 prod(i) 表示从 1i 的前缀积,那么要求 [j,i] 的区间积,需要 prod(i)/prod(j1)。可是有时候乘积太大需要取模,那么这时候的除法需要乘法逆元,但是 prod 可能很大,逆元数组存不下(这里是线性逆元),这时候就要用到这条结论:前缀积的逆元,就是逆元的前缀积

prei=j=1iajprei1=j=1naj1

我们可以得到递推式:prei1=ai+11×prei+11(1i<n)

也可以求单个值 aj1=prej1×prej1(1jn)

那么要线性求逆元,需要先求出 pren1,可以用费马小定理(p 是质数)或Exgcd。

总时间复杂度 O(n+logp),接近线性。

模板题:P5431【模板】乘法逆元 2

此题卡的很死,注意速度和运算空间

#include <bits/stdc++.h>
#define rei register int
#define ll long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define rep(i, s, n, c) for (register int i = s; i <= n; i+=c)
#define repd(i, s, n, c) for (register int i = s; i >= n; i-=c)
#define CHECK cout<<"WALKED"<<endl;
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}
#define pb push_back
#define ls id<<1
#define rs id<<1|1
const int INF = INT_MAX;
long long binpow(long long a, long long b, ll mod){long long res = 1;  while (b > 0){if (b & 1) res = res * a % mod;a = a * a % mod;  b >>= 1;  }  return res;}

using namespace std;
int a[5000006], pre[5000006], inv_pre[5000006], inv[5000006];
int main()
{
	int n; ll p, k;
	scanf("%d%lld%lld", &n, &p, &k);
	pre[0] = 1;
	for (register int i = 1; i <= n; i++) {
		a[i] = read();
		pre[i] = 1ll * pre[i - 1] * a[i] % p;
	}
	inv_pre[n] = binpow(pre[n], p - 2, p);
	for (int i = n; i > 0; i--) {
		inv[i] = 1ll * pre[i - 1] * inv_pre[i] % p;
		inv_pre[i - 1] = 1ll * inv_pre[i] * a[i] % p;
	}
	ll ans = 0;
	for (int i = 1, t = k; i <= n; i++) {
		ans = (1ll * inv[i] * t % p + ans) % p;
		t = 1ll * t * k % p;
	}
	printf("%lld\n", ans);
    return 0;
}
posted @   Vegdie  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示