同余
对于整数a,b,p,若a%p = b%p,记为
性质:
逆元
对于方程 ,x即为a在模b意义下的逆元,记为
(不是真正的-1次方)
换个简单的说法,对于整数 :
若 则有
若 则有
若 则不一定有
因为当
大于
时该式不成立
此时则需要用到逆元,记为
模
意义下的逆元,则有
exgcd求逆元
则存在一个值y使得
对于 有解的证明:
因为 ,所以ax实际是b的整数倍+1
相邻的两个数一定互素,因为他们的公共因子只有1
换种解释:
因此求出 的最小正整数解即为a在模b意义下的逆元
费马小定理
若p为素数,gcd(a,p) = 1,则有:
证明:
令
因为p为素数,有:
所以
根据同余的性质,有:
因为[1,p-1]中除1以外没有p的因子,所以(p-1)!不为p的倍数,则有:
得证
同样的对于前文提到的欧拉定理:
容易得到
在求解逆元的时候,若p为素数且gcd(a,p) = 1,也可以用快速幂根据费马小定理来求解
线性求逆元
因为是模p意义下的,所以下面的 均满足
对于n个数,若每次都用logn的方法求复杂度可能会太大
设为
的前缀积,
为
的逆元,
为
的逆元
可以得到 因为前i个数乘积的逆元乘上第i个数消去了第i个数的逆元
同理 即消去前i-1个数的乘积的逆元
只需要计算出 即可通过线性递推得到所有
的逆元
sum[0] = 1;
for(int i = 1;i <= n;i++)
{
a[i] = read();
s[i] = s[i-1] * a[i];
s[i] %= p;
}
//这里利用费马小定理求解,注意费马小定理的条件a,p互质
invs[n] = fastPow(s[n],p-2);
for(int i = n;i >= 1;i--)
{
inv[i] = (invs[i] * s[i-1]) % p;
invs[i-1] = (invs[i] * a[i]) % p;
}