三項式與組合數(lucas板子)

1 、三項式展開

2、排列組合

%%%大佬博客:https://blog.csdn.net/qq_34531807/article/details/79795261

1、當n,m都很小的時候直接用楊輝三角求

C(n,m)=C(n-1,m)+C(n-1,m-1)

2、利用乘法逆元

3、當n和m比較大,mod是素數且比較小的時候(10^5左右),通過Lucas定理計算

 

題目:https://ac.nowcoder.com/acm/contest/699/F

三項式展開+lucas+快速冪(板子)

#include<iostream>
#define ll long long
#define mod 10007
using namespace std;

ll qpow(int a,int b,int m)//pow(a,b)%m
{
	ll result = 1;
	ll base = a;
	while(b>0)
	{
		if(b&1==1)
		result=(result*base)%m;
		base=(base*base)%m;
		b>>=1;
	}
	return result;
}
//計算組合數取模
ll comp(ll a,ll b,int p)// num C(a,b)%p
{
	if(a<b)return 0;
	if(a==b)return 1;
	if(b>a-b)b=a-b;
	ll ans=1,ca=1,cb=1;
	for(ll i=0;i<b;i++)
	{
		ca=(ca*(a-i))%p;
		cb=(cb*(b-i))%p;
	}
	ans=(ca*qpow(cb,p-2,mod))%p;
	return ans;
}
ll lucas(ll n,ll m,ll p)
{
	ll ans=1;
	while(n&&m&&ans)
	{
		ans=(ans*comp(n%p,m%p,p))%p;
		n/=p;
		m/=p;
	}
	return ans;

}

int main(){
	ll a,b, c, d,e,f,g;
	cin>>a>>b>>c>>d>>e>>f>>g;
	ll ans=lucas(e+f,e,mod);
	//cout<<ans<<endl;
	ans*=lucas(d,g,mod);
	//cout<<ans<<endl;
	ans=(((ans*qpow(a,e,mod))%mod*qpow(b,f,mod))%mod*qpow(c,g,mod))%mod;
	cout<<ans<<endl;
	return 0; 
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章