乘法逆元

  • 快速幂求逆元 时间复杂度:\(O(\log p)\)
ll qow(ll x,ll y)
{
	ll res=1;
	while(y>0)
	{
		if(y&1)(res*=x)%=p;
		(x*=x)%=p;y>>=1;
	}
	return res;
}
  • 扩展欧几里得求逆元 时间复杂度\(O(\log p)\)
    证明:
    \(ax+py=1两边同时模p\)
    \(ax\%p+py\%p=1\%p\)
    \(ax\%p=1\%p\)
    \(ax\equiv1\pmod{p}\)
    所以同理可以证得\(ax+py=1的一组解(x,y),x 是a关于p的逆元,y是p关于a的逆元\)
void exgcd(int a, int b, int& x, int& y) {
  if (b == 0) {
    x = 1, y = 0;
    return;
  }
  exgcd(b, a % b, y, x);
  y -= a / b * x;
}
  • 线性求逆元(连续逆元)时间复杂度:\(O(n)\)
    证明:
    \(对于递归情况i^{-1},令k=\left\lfloor \frac{p}{i}\right\rfloor,j=p \mod i,有p=ki+j。在\mod p意义下会得到:{ki+j}\equiv0\pmod{p}\)
    两边同时乘\(i^{-1}*j^{-1}\)
    \(kj^{-1}+i^{-1}\equiv0\pmod{p}\)
    \(i^{-1}\equiv{-kj^{-1}}\pmod{p}\)
    \(i^{-1}\equiv{-\left\lfloor \frac{p}{i}\right\rfloor (p\%i)^{-1}}\pmod{p}\)
    ps:用\(p-\left\lfloor \frac{p}{i}\right\rfloor来防止负数\)
for(int i=1;i<=n;i++)
{
	if(i==1)lv[i]=1;
	else lv[i]=(p-p/i)*lv[p%i]%p;
	printf("%lld\n",lv[i]);
}
  • 线性求逆元(n个数)时间复杂度:\(O(n+\log p)\)
    计算n个数的前缀积,记为\(s_i\),然后使用快速幂或扩展欧几里得计算\(s_n\)的逆元,记为\(sv_n\)
    因为\(sv_n\)是n个数的积的逆元,所以当我们把它乘上\(a_n\)时,就会和\(a_n\)的逆元抵消,于是就得到了\(a_1\)\(a_{n-1}\)的积逆元,记为\(sv_n\)
    同理我们可以依次计算出所有的\(sv_i\),于是\(a_i^{-1}\)就可以用\(s_{i-1}*sv_i\)求得。
s[0]=1;
for(int i=1;i<=n;i++)s[i]=s[i-1]*a[i]%p;
lv[n]=qow(s[n],p-2);//快速幂
for(int i=n;i>=1;i--)lv[i-1]=lv[i]*a[i]%p;
for(int i=1;i<=n;i++)printf("%lld\n",s[i-1]*lv[i]%p);

原文地址:http://www.cnblogs.com/mkik/p/16851796.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性