同余与逆元

同余

对于整数a,b,p,若a%p = b%p,记为a\equiv b\ (mod\ p)

性质:

  • a\equiv a\ (mod\ p)
  • a\equiv b\ (mod\ p),c\equiv d\ (mod\ p)\Rightarrow a\equiv c\ (mod\ p),b\equiv d\ (mod\ p)
  • a\equiv b\ (mod\ p),x\equiv y\ (mod\ p)\Rightarrow ax\equiv by\ (mod\ p)

逆元

对于方程  ax\equiv 1\ (mod\ b)  ,x即为a在模b意义下的逆元,记为a^{-1}(不是真正的-1次方)

换个简单的说法,对于整数 a,b,p(a>b>0)

(a+b)\ mod\ p = c 则有 a = ((c-b)\ mod\ p + p)\ mod\ p

(a-b)\ mod \ p = c 则有 a = (c+b)\ mod\ p

(a*b)\ mod\ p = c 则不一定有a = (c/b)\ mod\ p 因为当a*b大于p时该式不成立

此时则需要用到逆元,记b^{-1}bp意义下的逆元,则有a = (c*b^{-1})\ mod\ p

exgcd求逆元

ax\equiv 1\ (mod\ b) \Rightarrow ax \ mod\ b = 1\ mod\ b 

则存在一个值y使得 ax + by = 1

对于 ax + by = 1 有解的证明:

因为 ax\equiv 1\ (mod\ b) ,所以ax实际是b的整数倍+1

相邻的两个数一定互素,因为他们的公共因子只有1

换种解释:gcd(a,a+1) = gcd((a+1)\ mod\ a,a) = gcd(1,a)

因此求出 ax + by = 1 的最小正整数解即为a在模b意义下的逆元

费马小定理

若p为素数,gcd(a,p) = 1,则有:

a^{p-1}\equiv 1\ (mod \ p)\ \Rightarrow \ a^p\equiv a\ (mod\ p)

证明:

令 b = \left \{ 1,2,3.....p-1 \right \}

因为p为素数,有:

gcd(b_i,p) = 1,gcd(a,p) = 1 

 所以  gcd(a*b_i,p) = 1        a*b_i\equiv 1\ (mod\ p) 

根据同余的性质,有:

a*1*a*2...a*(p-1) \equiv 1 \ (\ mod\ p)\Rightarrow a^{p-1}(p-1)!\equiv 1(\ mod\ p)

因为[1,p-1]中除1以外没有p的因子,所以(p-1)!不为p的倍数,则有:

gcd((p-1)!,p)= 1\Rightarrow (p-1)!\ \equiv 1\ (mod\ p)

a^{p-1}(p-1)!\equiv 1(\ mod\ p)\Rightarrow a^{p-1}\equiv 1\ (mod\ p) 得证

同样的对于前文提到的欧拉定理:

\varphi(p) = p-1  容易得到      a^{\varphi(p)}\equiv 1\ (mod\ p)

在求解逆元的时候,若p为素数且gcd(a,p) = 1,也可以用快速幂根据费马小定理来求解

线性求逆元

因为是模p意义下的,所以下面的 a_i 均满足 1\leqslant a_i<p

对于n个数a_1,a_2......a_n,若每次都用logn的方法求复杂度可能会太大

s_ia_i的前缀积,invs_is_i的逆元,a_i^{-1}a_i的逆元

可以得到  invs_i * a_i = invs_{i-1}  因为前i个数乘积的逆元乘上第i个数消去了第i个数的逆元

同理 a_i ^ {-1} = invs_i*s_{i-1}  即消去前i-1个数的乘积的逆元

只需要计算出 invs_n 即可通过线性递推得到所有 a_i 的逆元

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;
}

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值