CF1475E Advertising Agency

CF传送门

题目大意:有 n n n个博主,其中第 i i i个有 a i a_i ai个粉丝。你需要选出 k k k个,使得他们的粉丝总数最多。问有多少种选法,答案对 1 0 9 + 7 10^9+7 109+7取模。

思路:一道基础的组合计数

首先很自然的想到将序列 a a a降序排序。
显然我们要考虑的就是有多少个数和第 k k k个数相等,在选完比第 k k k个数大的数之后,从其中选取若干个,选够 k k k个,有多少方案
那么很简单的,我们用 p o s pos pos指出比第 k k k个数大的数的个数,用 c n t cnt cnt记录等于第 k k k大的数,那么 a n s = C c n t k − p o s ans=C_{cnt}^{k-pos} ans=Ccntkpos

先放个我常用的组合数板子:
( 1 0 18 10^{18} 1018记得用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;
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学不会数据库

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值