Wraith_Fiee的博客

CF1475E Advertising Agency

2021-11-13 · 3 min read
组合计数 Codeforces

CF传送门

题目大意:有nn个博主,其中第ii个有aia_i个粉丝。你需要选出kk个,使得他们的粉丝总数最多。问有多少种选法,答案对109+710^9+7取模。

思路:首先很自然的想到将序列aa降序排序。
显然我们要考虑的就是有多少个数和第kk个数相等,在选完比第kk个数大的数之后,从其中选取若干个,选够kk个,有多少方案
那么很简单的,我们用pospos指出比第kk个数大的数的个数,用cntcnt记录等于第kk大的数,那么ans=Ccntkposans=C_{cnt}^{k-pos}

先放个常用的组合数板子:
(101810^{18}记得用Lucas,这里就不放了)

#include <bits/stdc++.h>
using namespace std;
const int N=1e3+10,mod=1e9+7;
typedef long long ll;
ll fac[N];
void init(){
	fac[0]=1;
	for(int i=1;i<=N;i++) fac[i]=fac[i-1]*i%mod;
}
ll power(ll a,ll b){
	ll res=1;
	for(;b;b>>=1){
		if(b&1) res=res*a%mod;
		a=a*a%mod;
	}
	return res;
}
ll C(ll n,ll m){
	return fac[n]*power(fac[m],mod-2)%mod*power(fac[n-m],mod-2)%mod;
}

Code

#include <bits/stdc++.h>
using namespace std;
const int N=1e3+10,mod=1e9+7;
typedef long long ll;
ll fac[N];
void init(){
	fac[0]=1;
	for(int i=1;i<=N;i++) fac[i]=fac[i-1]*i%mod;
}
ll power(ll a,ll b){
	ll res=1;
	for(;b;b>>=1){
		if(b&1) res=res*a%mod;
		a=a*a%mod;
	}
	return res;
}
ll C(ll n,ll m){
	return fac[n]*power(fac[m],mod-2)%mod*power(fac[n-m],mod-2)%mod;
}
bool cmp(int a,int b){return a>b;}
int t,n,k,a[N];
int main(){
	init();
	cin>>t;
	while(t--){
		cin>>n>>k;
		for(int i=1;i<=n;i++) cin>>a[i];
		sort(a+1,a+1+n,cmp);
		int cnt=0,pos=0;
		for(int i=1;i<=n;i++){
			if(a[i]>a[k]) pos=i;
			if(a[i]==a[k]) cnt++; 
		}
		ll ans=C(cnt,k-pos); 
		cout<<ans<<endl;
	}
	return 0;
}
 
在吹不出褶皱的日子里发光
Powered by Gridea