思路:
先排序,取最大的在剩余左边任意找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; }