一.定义
(及如何理解)
如果a*x≡1 (mod p),且gcd(a,p)=1(a与p互质),则称a关于模p的乘法逆元为x。(from Wikipedia)
a*x≡1 (mod p) 表示 a乘一个数x并模p等于1,即 a*x%p=1;看上去就是同余定理的一个简单等式。
而x 为 a 的逆元,记为x=a-1,所以我们也可以称 x 为 a 在mod b意义下的倒数(定义了剩余系中的除法),
什么意思呢? 可以理解为在x的倒数上加了个限定:
倒数定义为a*x=1,则x为a的倒数;
而逆元为:a*x%p=1;
用处:一般用于求 a/b (mod p) 的值(p 通常为质数),是解决模意义下分数数值的必要手段。
(比如某道水题让你对结果%p,而计算过程中有除法运算。。)
二.求解
1.扩展欧几里得算法求解逆元
我们知道,a*x≡1 (mod p) 就是 a*x%p=1 也就是 a*x+p*y=1
而扩展欧几里得算法就是用来求线性同余方程a∗x≡c ( mod b ),只不过此时c=1;
#include#include #define R register int #define ll long long using namespace std; int n,p; void ex_gcd(ll a,ll b,ll& x,ll& y) { if(!b) x=1,y=0; else ex_gcd(b,a%b,y,x),y-=a/b*x; } int main() { scanf("%d%d",&n,&p);//求1到n在mod p意义下的逆元 for(R i=1;i<=n;i++) { ll x,y; ex_gcd(a,p,x,y); x=(x%p+p)%p; printf("%d\n",x); } return 0; }
2.费马小定理和快速幂求解逆元(此时p为质数)
由费马小定理可知:ap-1≡1 (mod p)
所以a*ap-2≡1 (mod p)
即ap-2就是a在mod p意义下的逆元
#include#include #include #define R register int #define ll long long using namespace std; int n,p; ll q_pow(ll x,ll ind,ll mod) { x%=mod; ll a=1; for(;ind;ind>>=1,(x*=x)%=mod) if(ind&1) (a*=x)%=mod; return a; } int main() { scanf("%d%d",&n,&p);//求1到n在mod p意义下的逆元 for(R i=1;i<=n;i++) printf("%lld\n",q_pow(i,p-2,p)); return 0; }
若p为合数,则需要用到欧拉函数和欧拉定理(详见https://www.cnblogs.com/Jackpei/p/10372392.html)
#include#include #include #define R register int #define ll long long using namespace std; static ll a,p; inline ll q_pow(ll x,ll ind,ll mod) { x%=mod; register ll a=1; for(;ind;ind>>=1,(x*=x)%=mod) if(ind&1) (a*=x)%=mod; return a; } inline int phi(int n) { R ans=1; for(R i=2;i*i<=n;++i) if(n%i==0) { n/=i; ans*=i-1; while(n%i==0) n/=i,ans*=i; } if(n>1) ans*=n-1; return ans; } int main() { scanf("%lld%lld",&a,&p);//求a在mod p 意义下的逆元 printf("%lld\n",q_pow(a,phi(p)-1,p)); return 0; }
3.O(n)的线性算法
原题:P3811 【模板】乘法逆元 https://www.luogu.org/problemnew/show/P3811
求 [1,n] 区间中每个数的逆元,其实这是一种递推。。。
我们设 inv[i] 表示i的逆元,设 p=k*i+r (1 则左右同乘 r-1 * i-1 :k*r-1+i-1≡0 (mod p) 所以:i-1≡ -k*r-1 (mod p); 易知:r-1=inv[p%i],k=p/i 所以:i-1 = (-p/i+p) * inv[p%i]%p 而由逆元定义可知:inv[1]=1 (mod p),你就可以开始递推了。 。。。还未学会。。。安利一发zjp_shadow大佬的blog:https://www.cnblogs.com/zjp-shadow/p/7773566.html (写得太好了) 如有错误,恳请您指正(我太菜了);如有不理解,可留言,我会尽量回复。。。(高中生(逃)。。) by Jackpei 2019.2.10#include
4.阶乘逆元