逆元

//逆元小结:
·逆元的定义: 
  a*x==1(mod p)的解,记作a^(-1),inv(a);
  
·作用:
计算a/b%p,为了不损失精度,应计算a*b^-1%p;(a*inv(b))%p;

·求逆元 

1.快速幂求逆元(p一定要是质数): 单个复杂度O(logn),连续O(nlogn)

根据费马小定理,a,p,互质 ,且p是质数 则有
    a^(p-1) == 1 (mod p)
则:
	a*a^(p-2) == 1 (mod p)
即a的逆元是a^(p-2)%p;
	fact[0]=infact[0]=1;
    for(int i=1;i<N;i++)
    fact[i]=fact[i-1]*i%p,infact[i]=infact[i-1]*fpow(i,p-2,p)%p;//递推求i!,i!的逆元 

2.exgcd求逆元:
   走快速幂要求p一定是质数,而exgcd求逆元只需要满足gcd(a,b)==1。
#include<bits/stdc++.h> 
using namespace std;
#define int long long
int exgcd(int a,int b,int &x,int &y)
{
	if(!b){  x=1,y=0; return a; }
	int d=exgcd(b,a%b,y,x);
	y-=a/b*x;
	return d;
}
signed main()
{
	int a,b,x,y; cin>>a>>b;
	int d=exgcd(a,b,x,y);
	cout<<(d==1?(x+b)%b:-1);
} 
    
3.线性递推逆元:  复杂度O(n)
记i的逆元为inv[i],则有如下递推 :
	
	inv[i]=(p-p/i)*inv[p%i]%p;
注意,线性递推求逆元时,注意将0,1位上赋值为1!!! 


·应用:
(1).精确计算a/b%p 的结果
(2).组合数计算
   
    int n,m; cin>>n>>m;
    cout<<fact[n]*infact[n-m]%p*infact[m]%p<<endl;
	

 
  

24/8/27   要开学了(*/ω\*)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值