【csp模拟赛3】组合数学

思路:

  先排序,取最大的在剩余左边任意找k-1个数,所以是排列组合,费马小定理求逆元,预处理阶乘,注意要取模。。

代码:

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define int long long
#define p 1000000007
using namespace std;
const int N = 105000;
int n,k,a[N],sum,jie[N];
int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int ksm(int x,int y)
{
	int res=1;
	for(;y;x=(x*x)%p,y>>=1){
		if(y&1)res=(res*x)%p;
	}
	return res%p;
}
void jiec()
{
	jie[0]=1;jie[1]=1;
	for(int i=2;i<=100050;i++)
	jie[i]=(jie[i-1]%p*i%p)%p;
}
int C(int n,int m)
{
	int ni=ksm(jie[m]*jie[n-m]%p,p-2);
	int ans=(jie[n]%p*ni%p)%p;
	return ans;
}
signed main()
{
	#ifdef yilnr
	#else
	freopen("trees.in","r",stdin);
	freopen("trees.out","w",stdout);
	#endif
	jiec();
	n=read();k=read();
	for(int i=1;i<=n;i++)a[i]=read();
	sort(a+1,a+n+1);
	for(int i=n;i>=k;i--)
	{
		sum+=( C(i-1,k-1)*a[i] );
		sum%=p;
	}
	printf("%lld
",sum);
	fclose(stdin);fclose(stdout);
	return 0;
}

  

原文地址:https://www.cnblogs.com/yelir/p/11545674.html