乘法逆元
1,乘法逆元
ax≡1(mod p),且gcd(a,p)=1(a,p互质),则a关于p的乘法逆元为x
2,费马小定理
假如a是一个整数,p是一个质数,那么( ap - a )是p的倍数,可以表示为
ap ≡a(mod p)
如果a不是p的倍数,p是一个质数,则
ap-1 = 1(mod p)
3,扩展欧几里得
已知整数a、b,扩展欧几里得算法可以在求得a、b的最大公约数的同时,能找到整数x、y(其中一个很可能是负数),使它们满足ax+by=gcd(a,b)
费马小定理求逆元:
ap-1=1(mod p) ,则逆元x=ap-2(快速幂求)
扩展欧几里得求逆元:
ax≡1(mod p),则ax-py=1,把-y写成+的形式,即ax+py=1,求得逆元
1,扩展欧几里得求逆元(a,b互质,否则无解)
函数返回值为a,b的最大公约数,x为a的逆元
1 int ex_gcd(int a,int b,int &x,int &y) 2 { 3 int ret,temp; 4 if(b==0){ 5 x = 1; 6 y = 0; 7 return a; 8 } 9 ret = ex_gcd(b,a%b,x,y); 10 temp = x; 11 x = y; 12 y = temp-a/b*y; 13 return ret; 14 }
2,快速幂求逆元( p是质数)
ap-1=1(mod p) ,则逆元x=ap-2
1 long long quick_inv(long long a,int p){ 2 int s = p-2; 3 long long ans = 1,pos = a; 4 while(s){ 5 if(s%2) ans = ans*pos%p; 6 pos = pos*pos%p; 7 s/=2; 8 } 9 return ans%p; 10 }
3,通过递推求1~n的逆元(n较小,p是质数)
公式推导:记 i 的逆元为 i-1
p = k*i+r, 令r < i,则 k = p/i , r = p%i
k*i + r ≡ 0 (mod p)
↓( 两边同时乘以 r-1,i-1)
k*r-1 + i-1 ≡ 0(mod p)
i-1 = -k * r -1 (mod p)
i-1 = - (p / i) * inv[p%i]
i-1 = (p - p/i) *inv[p%i]
inv[1] = 1;
1 //求1~n的逆元,p为模数,n<=p-1 2 void n_inv(int n){ 3 inv[1] = 1; 4 for(int i = 2;i <= n ;i++){ 5 inv[i] = (p-p/i)*inv[p%i]%p; 6 } 7 }
4,通过递推求1!~ n! 的逆元
公式:inv[i] = inv[i+1] * (i+1)%p
void fac_inv(int n){ fac[1] = 1; for(int i = 2;i <= n;i++) fac[i] = fac[i-1]*i; inv = quick_inv(fac[n],p); for(int i = n-1;i>0;i--) inv[i] = inv[i+1]*(i+1)%p; }

浙公网安备 33010602011771号