乘法逆元
什么是乘法逆元?
若整数 \(b,m\) 互质,并且\(b|a\) ,则存在一个整数\(x\) ,使得 \(\frac{a}{b}\equiv ax\mod m\) 。
称\(x\) 是\(b\) 模\(m\) 的乘法逆元,记作\(b^{-1} \mod m\) 。
- 而\(a/b\equiv a*b^{-1}\equiv a/b*b*b^{-1} \mod m\)
- 其实就是\(b*b^{-1} \equiv 1\mod m\)
其实就是模意义下除法变乘法。
怎么求乘法逆元?(费马小定理)
- 费马小定理:如果p是一个质数,而整数a不是p的倍数,则有\(a^{p-1}≡1\mod p\)
- 也就是说\(a*a^{p-2}≡1\mod p\)
- 也就是说\(p\) 是素数的时候,其乘法逆元是\(a^{p-2}\)
int qpow(int a, int b, int p){
int ans=1;
while(b){
if(b&1)ans=ans*a%p;
b>>=1;
a=a*a%p;
}
return ans;
}
int inv(int a, int p){
return qpow(a,p-2,p);
}
- 那\(p\) 不是素数呢?——扩展欧几里得算法
扩展Euclid求逆元
- 求解\(ax\equiv1\mod m\)
- 即\(ax-my=1\)
- 这个\(x\) 就是\(a \mod m\) 的逆元
- 用扩欧求\(x\) 的话,这个\(y\) 的正负对\(x\) 无影响。
//ax+by=gcd(a,b)
int exgcd(int a,int b,int &x,int &y){
if(b==0){
x=1;
y=0;
return a;
}
int d=exgcd(b,a%b,x,y);
int z=x;
x=y;
y=z-a/b*y;
return d;
}
//inv(a)
int inv(int a,int p){
int x,y;
int d=exgcd(a,p,x,y);
return d==1?(x%p+p)%p:-1;
}