乘法逆元

定义

如果有\(a x \equiv 1(\bmod b)\),则称\(x\)\(a \ mod \ b\)的逆元,记作\(a^{-1}.\)

性质

\[\frac{x}{y} \equiv x \times y^{-1} \quad(\bmod p) \]

计算方法
  • 扩展欧几里得

限制:

\[gcd(a,b)=1 \]

  #include <iostream>
  using namespace std;

  void Exgcd(int a , int b , int &x , int &y){
    	if(!b) x = 1 , y = 0;
    	else Exgcd(b , a % b , y , x) , y -= (a / b) * x;
  }

  int main(){
    	int n , p , x , y;
    	ios::sync_with_stdio(false);
    	cin >> n >> p;
   	 	for(int i = 1; i <= n; i++){
      		Exgcd(i , p , x , y);
      		while(x < 0) x += p;
      		x %= p;
      		cout << x << endl;
    	}
    	return 0;
  }
  • 快速幂

运用费马小定理

\(p\)为质数,\(a\)为正整数,且\(a,p\)互质,则\(a^{p-1} \equiv 1 \ ( \bmod \ p)\)

\(ax \equiv 1\ (\bmod\ b)\)\(\ a^{b-1} \equiv 1\ (\bmod\ b),\)

\(a x \equiv a^{b-1}\ (\bmod\ b),\)

\(x \equiv a^{b-2}\ (\bmod\ b).\quad\)故可用快速幂求解:

int fpm(ll a, ll b, ll p){
		ll ans = 1; a %= p;
		for(; b; b >>= 1,(a *= a) %= p) if (b & 1) (ans *= a) %= p;
		return ans;
}	
int main(){
		ll x = fpm(a, p - 2, p);//x为a在mod p意义下的逆元
}

  • 线性求逆元

    用于求一连串数字对于一个相同模数$\ p\ $的逆元

    显然,\(1^{-1} \equiv 1\ (\bmod\ p)\)

    \(\ p=k * i+r\ ,(1<r<i<p),\)那么在\((mod\ p)\)意义下有

    \[k * i+r \equiv 0 \quad(\bmod\ p) \]

    两侧同乘\(i^{-1},r^{-1}\)

    \[k * r^{-1}+i^{-1} \equiv 0 \quad(\bmod\ p) \]

    \[i^{-1} \equiv-k * r^{-1} \quad(\bmod\ p) \]

    \[i^{-1} \equiv-\left\lfloor\frac{p}{i}\right\rfloor *(p \bmod i)^{-1} \quad(\bmod\ p) \]

    可以得到递推代码:

    inv[1] = 1;
     for(int i = 2; i < p; ++ i)
     	inv[i] = (p - p / i) * inv[p % i] % p;
    
posted @ 2022-04-11 22:13  skyliyu  阅读(33)  评论(0编辑  收藏  举报