逆元
定义:
逆元指在某种运算中,对一个数a进行逆运算可以等价为对一个数b进行原运算,此时称a与b互为逆元。
本文中的逆元均指模算术中的乘法逆元,即对于一个数a,如果存在b满足a*b≡1(mod p),则称a与b在模p意义下互为逆元。
由于同余的性质,我们在进行模算术除法时不能简单地除一个数,而应该乘该数的逆元。
求法:
(1)单点逆元
a*b≡1(mod p)等价于p|a*b-1,整理得a*b-p*k=1,b,k为未知变量。此时可以用扩展欧几里得求解。时间复杂度O(log2 max(a,b))。
特别地,如果p为质数,若p整除a,则显然无解,若p不整除a,则gcd(a,p)=1,由费马小定理,ap-1 ≡1(mod p),即a*ap-2 ≡1(mod p)。所以ap-2 与a互为逆元。可用快速幂求解。时间复杂度O(log2 p)。
(2)区间逆元
如果要求1~n的逆元,如果对每个值求单点逆元,复杂度将达O(nlog2 p),而存在一种逆元的递推求法,即从1~n-1的逆元可O(1)求出n的逆元。
原理:
记a的逆元为a-1 。此时我们求i的逆元。
设p=i*q+r(0≤r<i),两边取模得i*q+r≡0(mod p),整理得r≡-i*q(mod p)。
两边同时乘i和r的逆元,得i-1 ≡-q*r-1 。又因为r-1 之前已经求出,所以可以O(1)算出。随后只需根据最小非负整数的要求进行调整即可。
代码:
inv[1]=1;//1的逆元总是1
for(int i=2;i<=n;i++){inv[i]=(p-p/i*inv[p%i]%p)%p;}
例题:
NOIP2012 同余方程 题目链接
题意:求一个数a在模b意义下的逆元,a,b≤2e9。
题解:扩展欧几里得即可。
Luogu P3811 【模板】乘法逆元 题目链接
题意:求1~n在模p意义下的逆元。1≤n≤3e6,n<p<20000528
题解:线性递推即可。