AT5341 [ABC156D] Bouquet

题意:
Akari 有 n 种不同的花,她可以选择其中一种或多种花做成花束。但是 Akari 不喜欢花的种数恰好为 a 或 b 的花束。求出她组合花的合法方案总数,对 10^9+7 取模。
推出公式:ans=(2^n)-C(n,a)-C(n,b)-1
由于n,a,b均小于模数,所以直接算组合数即可,不需要Lucas定理。
下面给出的代码复杂度为:O(min(m,n-m))
适用于在m比较小,或m与n比较接近的情况。
#include 
#define int long long
using namespace std;
const int MOD=1e9+7ll;
int n,a,b,ans;

inline int pow(int a,int n)
{
     
	int res=1ll;
	while (n)
	{
     
		if (n&1ll) res=res*a%MOD;
		a=a*a%MOD;
		n>>=1ll;
	}
	return res%MOD;
}

inline int C(int n,int m)
{
     
	if (n<m) return 0ll;
	if (n==m || !m) return 1ll;
	if (m<n-m) m=n-m;
	int a=1ll;
	for (register int i=m+1; i<=n; ++i) a=a*i%MOD;
	int b=1ll;
	for (register int i=1; i<=n-m; ++i) b=b*i%MOD;
	return a*pow(b,MOD-2ll)%MOD;
}

signed main(){
     
	scanf("%lld%lld%lld",&n,&a,&b);
	ans=((pow(2ll,n)-C(n,a)-C(n,b)-1ll)%MOD+MOD)%MOD;
	printf("%lld\n",ans);
return 0;	
}

你可能感兴趣的:(组合数学)