Luogu P3811 [模板]乘法逆元 题解报告

题目传送门

【题目大意】

给定$n$,求$1~n$在膜$p$意义下的乘法逆元。

【思路分析】

好的原本我只会求单个数的逆元,然后被告知了这道题之后发现自己不会做(我果然还是太弱了),于是就学了一下递推求逆元。

设$p=k*i+r$,则可得$k*i+r\equiv0(mod\ p)$,然后乘上$i^{-1},r^{-1}$即可得到$k*r^{-1}+i^{-1}\equiv0(mod\ p)$

由于$k=\lfloor \frac{p}{i}\rfloor,r=p\ mod\ i$,所以$i^{-1}\equiv -\lfloor \frac{p}{i}\rfloor*(p\ mod\ i)(mod\ p)$

于是我们就得到递推式啦!QwQ

$$inv[i]=(-p/i*inv[p\ mod\ i]+p)mod\ p$$

【代码实现】

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 #define g() getchar()
 8 #define rg register
 9 #define go(i,a,b) for(rg int i=a;i<=b;i++)
10 #define back(i,a,b) for(rg int i=a;i>=b;i--)
11 #define db double
12 #define ll long long
13 #define il inline
14 #define pf printf
15 #define mem(a,b) memset(a,b,sizeof(a))
16 using namespace std;
17 int fr(){
18     int w=0,q=1;
19     char ch=g();
20     while(ch<‘0‘||ch>‘9‘){
21         if(ch==‘-‘) q=-1;
22         ch=g();
23     }
24     while(ch>=‘0‘&&ch<=‘9‘) w=(w<<1)+(w<<3)+ch-‘0‘,ch=g();
25     return w*q;
26 }
27 const int N=3e6+2;
28 int n,p;
29 ll inv[N];
30 int main(){
31     //freopen("","r",stdin);
32     //freopen("","w",stdout);
33     n=fr();p=fr();
34     inv[1]=1;pf("%lld\n",inv[1]);
35     go(i,2,n) inv[i]=(p-p/i)*inv[p%i]%p,pf("%lld\n",inv[i]);
36     return 0;
37 }

代码戳这里

原文地址:https://www.cnblogs.com/THWZF/p/11569174.html

时间: 2024-10-10 04:47:35

Luogu P3811 [模板]乘法逆元 题解报告的相关文章

[模板]乘法逆元

本博客所有代码基于题目 luogu_P3811 逆元: 一般用于求 (a/b) mod p  定义: 若 a*x ≡ 1 (mod p) ,且 a 与 p 互质,那么我们就能定义: x 为 a 的逆元,记为 a^-1 ,所以我们也可以称 x 为 a 的倒数(mod p意义下). 所以对于 (a/b) mod p ,我们就可以求出 b 在 mod p 意义下的逆元,然后乘上 a ,再 mod p ,就是这个乘法逆元的值了. 求法: First:费马小定理 定理内容:如果 a , p 互质,那么 a

luogu P3811线性求逆元

首先扩O:T了一个点(因为上界松),83分. #include <cstdio> using namespace std; int n, p; void exgcd(int a, int p, int &b, int &x){ if (p==0){ b=1, x=0; return; } exgcd(p, a%p, b, x); int tmp=b; b=x; x=tmp-a/p*x; return; } int main(){ scanf("%d%d",

题解 P3811 【模板】乘法逆元

题意求\(i\)在模\(p\)意义下的逆元\(\frac{1}{i}\)即\(inv(i)\).题目数据范围很明显规定了要求一个线性求逆元的算法. 令\(p=ai+b\),则有: \[ai+b\equiv 0(\mod p)\] 移项得: \[ai\equiv -b(\mod p)\] 系数化简得: \[i\equiv -\frac{b}{a}(\mod p)\] 取倒数得: \[\frac{1}{i} \equiv -\frac{a}{b}(\mod p)\] 即 \[inv(i) \equi

P3811 【模板】乘法逆元

P3811 [模板]乘法逆元 题目背景 这是一道模板题 题目描述 给定n,p求1~n中所有整数在模p意义下的乘法逆元. 输入输出格式 输入格式: 一行n,p 输出格式: n行,第i行表示i在模p意义下的逆元. 输入输出样例 输入样例#1: 10 13 输出样例#1: 1 7 9 10 8 11 2 5 3 4 说明 1≤n≤3×10?6??,n<p<20000528 输入保证 p 为质数. 我们有三种办法求逆元 由欧拉定理可知 当gcd(a,n)==1 时 我们有 Aφ(n-1)≡ 1(mod

洛谷 P3811 【模板】乘法逆元 如题

P3811 [模板]乘法逆元 时空限制1s / 256MB 题目背景 这是一道模板题 题目描述 给定n,p求1~n中所有整数在模p意义下的乘法逆元. 输入输出格式 输入格式: 一行n,p 输出格式: n行,第i行表示i在模p意义下的逆元. 输入输出样例 输入样例#1: 10 13 输出样例#1: 1 7 9 10 8 11 2 5 3 4 说明 1 \leq n \leq 3 \times 10 ^ 6, n < p < 200005281≤n≤3×106,n<p<20000528

[洛谷P3811]【模板】乘法逆元

题目大意:给你n和质数p,求1~n在模p意义下的乘法逆元(n<p). 解题思路:由于$n<p<20000528$,所以扩展欧几里得是会超时的.这儿就要用到线性推逆元大法辣!→不懂戳这里← 注意乘法可能会超过int,所以计算时先转化为long long即可. C++ Code: #include<cstdio> int n,p,inv[20000529]; int main(){ scanf("%d%d",&n,&p); puts("

【模板】求1~n的整数的乘法逆元

洛谷3811 先用n!p-2求出n!的乘法逆元 因为有(i-1)!-1=i!-1*i (mod p),于是我们可以O(n)求出i!-1 再用i!-1*(i-1)!=i-1 (mod p)即是答案 1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 #include<cmath> 6 #include<algorithm> 7

【题解】POJ1845 Sumdiv(乘法逆元+约数和)

POJ1845:http://poj.org/problem?id=1845 思路: AB可以表示成多个质数的幂相乘的形式:AB=(a1n1)*(a2n2)* ...*(amnm) 根据算数基本定理可以得约数之和sum=(1+a1+a12+...+a1n1)*(1+a2+a22+...+a2n2)*...*(1+am+am2+...+amnm) mod 9901 对于每个(1+ai+ai2+...+aini) mod 9901=(ai(ni+1)-1)/(ai-1) mod 9901 (等比数列

T106021 【模板】乘法逆元(快速幂)

题目地址 注意点: 使用exgcd求乘法逆元需额外进行(相对)较多操作,建议使用快速幂求乘法逆元. #include<cstdio> #include<iostream> #define ll long long using namespace std; int n,p; int poww(int a,int b){ ll ans=1,tmp=a; while(b){ if(b&1){ ans*=tmp; ans%=p; } tmp=tmp*tmp; tmp%=p; b&g