(a/b)%p=1,若存在一个a’使得(a*a’)%p=1,则a’就是a关于p的逆元,a与a’互为逆元(a与p互质)
求解逆元的方法有三种:
1.利用费马小定理
a^(p-1)=1(mod p),则a*a^(p-2)=1(mod p),所以a关于p的逆元就是a^(p-2),用快速幂求解
LL power(int a,int n,int p)
{
LL ret = 1, res = a;
while (n) {
if (n & 1) ret = (ret*res) % p;
res = (res*res) % p;
n >>= 1;
}
return ret;
}
LL fun(int a, int p)
{
return power(a, p - 2,p);
}
2,拓展欧几里得算法
a*x+b*y=1(a,b互质有解)
这个解中的x就是a关于b的逆元,,y就是b关于a的逆元
证明:
两边同时求余b
a*x % b + b*y % b = 1 % b
a*x % b = 1 % b
a*x = 1 (mod b)
同理可以证明y是b关于a的逆元
求出来的结果中x可能是负数,(x%b+b)%b就是最小的正数解
void e_gcd(int a,int b,int &x,int &y)
{
if(b==0){
x=1;y=0;
return;
}
e_gcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
}
int cal(int a,int b)
{
int x,y;
e_gcd(a,b,x,y);
int ans=x%b;
if(ans<=0) ans+=b;
return ans;
}
3,
当p是个质数的时候有
inv(a) = (p - p / a) * inv(p % a) % p(inv表示逆元)
证明:
设x = p % a,y = p / a
于是有 x + y * a = p
(x + y * a) % p = 0
移项得 x % p = (-y) * a % p
x * inv(a) % p = (-y) % p
inv(a) = (p - y) * inv(x) % p
于是 inv(a) = (p - p / a) * inv(p % a) % p
然后一直递归到1为止,因为1的逆元就是1
LL inv(LL t, LL p) {//求t关于p的逆元,注意:t要小于p,最好传参前先把t%p一下
return t == 1 ? 1 : (p - p / t) * inv(p % t, p) % p;
}
感谢原博主
原博文地址:http://www.cnblogs.com/linyujun/p/5194184.html