[模板] 数学基础:逆元/exGCD/exCRT/Lucas定理/exLucas
Posted ubospica
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[模板] 数学基础:逆元/exGCD/exCRT/Lucas定理/exLucas相关的知识,希望对你有一定的参考价值。
方便复制
exgcd
用途
解不定方程 $ ax+by = c $
void exgcd(ll a,ll b,ll& x,ll& y,ll& d){
b==0?(x=1,y=0,d=a):(exgcd(b,a%b,y,x,d),y-=x*(a/b));
}
//use
ll a,b,c;
ll m,x,y;
exgcd(a,b,x,y,m);
if(c%m!=0)cout<<"No
"; //无解
else{
c/=m,x*=c,y*=c,a/=m,b/=m;
//令x取最小非负整数
x1=x%b;if(x1<0)x1+=abs(b);
y1=(c-a*x1)/b;
//令y取最小非负整数
y1=y%a;if(y1<0)y1+=abs(a);//(y>=0?y%a:y%a+abs(a));
x1=(c-b*y1)/a;
}
逆元
//1:qp(n,nmod-2)
//2
ll inv(ll n){
ll x,y,d;
exgcd(n,p,x,y,d);
return x%p+(x<0?p:0);
}
excrt
用途
解线性同余方程组 $ x equiv a_i pmod{m_i} $
代码
ll excrt(ll *a,ll *m,ll n){
ll a0=a[1],m0=m[1],x,y,g;
rep(i,2,n){
g=exgcd(m0,m[i],x,y);
if((a[i]-a0)%g!=0)return -1;
x=(a[i]-a0)/g*x%(m[i]/g);
a0+=x*m0;
m0=m0/g*m[i];
a0%=m0;
}
return a0<0?(a0%m0+m0):(a0%m0);
}
Lucas定理
内容
设(n=(a_0a_1dots a_k)_p),(m=(b_0b_1dots b_k)_p)
[ inom n mequiv prod _{i=0}^kinom {a_i} {b_i} mod p ].
也即
[ inom n m equiv inom {lfloor frac{n}{p}
floor} {lfloor frac{m}{p}
floor} cdot inom {n mod p} {m mod p} mod p]
代码
ll c(ll n,ll m){
if(m<0||m>n)return 0;
return fact(n)*inv(fact(m)*fact(n-m)%p)%p;
}
ll lucas(int n,int m){//c(n,m)%p
return m?lucas(n/p,m/p)*c(n%p,m%p)%p:1;
}
exLucas
以上是关于[模板] 数学基础:逆元/exGCD/exCRT/Lucas定理/exLucas的主要内容,如果未能解决你的问题,请参考以下文章