除法逆元入门
对于m=(a/b)(mod p)问题
由于除法不能用同余定理,我们需要将除法转换成乘法
( a / b ) % p =a * inv ( b , p ) %p =( a%p * inv ( b , p )%p ) %p
接下来就是乘法求逆元了,
可以看博客链接 乘法逆元数论
乘法
逆元
扩展欧几里得算法
要求a,n互为素数,存在唯一解
代码部分
int extgcd(int a, int b, int& x, int& y)
{
int d = a;
if(b != 0)
{
d = extgcd(b, a % b, y, x);
y -= (a / b) * x;
}
else
{
x = 1;
y = 0;
}
return d;
}
int mod_inverse(int a, int n)
{
int x, y;
extgcd(a, n, x, y);
return (n + x % n) % n;
}
///mod_inverse为对n取模a的逆元
费马小定理
在n为素数的情况下,对任意的a都有a^n≡a(mod n)
如果a无法被n整除,则有a^(n-1)≡1(mod n)
可以在n为素数的情况下求出一个数的逆元,a×a^(n-2)≡1(mod n),这时候,a^(n-2)为a的逆元。
代码部分
///这里用到了整数快速幂
ll mult(ll a,ll n) //求a^n%mod
{
ll s=1;
while(n)
{
if(n&1)s=s*a%mod;
a=a*a%mod;
n>>=1;
}
return s;
} //mult(a,n-2);
欧拉函数
简单介绍一下欧拉函数:在数论,对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目(φ(1)=1)。
如果对欧拉函数有兴趣的可以看看:欧拉函数
令φ(n)表示小于等于n且与n互素的正整数的个数。
如果a和n互质,则有a^φ(n)≡1(mod n),即 a×a^(φ(n)−1)≡1(mod n),那么a^(φ(n)−1)为a的逆元。
在n为质数的时候φ(n) = n - 1。
代码部分
///欧拉函数
int euler(int n)
{
int res = n;
for(int i = 2; i * i <= n; i++)
{
if(n % i == 0)
{
res = res / i * (i - 1);
while(n % i == 0) n /= i;
}
}
if(n != 1) res = res / n * (n - 1);
return res;
}
///求对mod = n,a的逆元
ll mult(ll a,ll n)
{
ll s=1;
while(n)
{
if(n&1)s=s*a%mod;
a=a*a%mod;
n>>=1;
}
return s;
} //mult(a, euler(n)-1);
最后加上一个欧拉函数打标的函数
int euler[maxn];
void euler()
{
for(int i = 0; i < maxn; i++) euler[i] = i;
for(int i = 2; i < maxn; ++i)
{
if(euler[i] == i)
{
for(int j = i; j < maxn; j += i)
{
euler[j] = euler[j] / i * (i - 1);
}
}
}
}