标签:排序 ons name 最小 题意 inf 最小值 组合 amp
https://atcoder.jp/contests/abc151/tasks/abc151_e
题意:给你n个数,从中任意选出k个数作为一组,求出任意组合的最大值-最小值之和。
解法:排序,前缀和和后缀和,组合规律。
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<algorithm>
#include<iostream>
#include<map>
#define inf 0x3f3f3f3f
#define ll long long
#define maxx 5000000
#define mod 1000000007
using namespace std;
const int N = 100002;
ll a[N] , sum1[N] , sum2[N] , fac[N] , inv[N];
ll quickpow(ll a, ll b)
{
ll ans = 1 ;
while(b)
{
if(b&1)
{
ans = ans * a % mod ;
}
b >>= 1 ;
a = a * a % mod ;
}
return ans%mod;
}
void init()
{
fac[0] = fac[1] = inv[0] = inv[1] = 1 ;
for(int i = 2 ; i <= N-2 ; i++) fac[i] = fac[i-1] * i % mod;
inv[N-2] = quickpow(fac[N-2] , mod-2);
for(int i = N -3 ; i >= 2 ; i--) inv[i] = inv[i+1] * (i+1) % mod;
}
ll C(int n , int m)
{
return fac[n]%mod * inv[m]%mod * inv[n-m]%mod;
}
int main()
{
init();
ll n , k ;
scanf("%lld%lld" , &n , &k);
for(int i = 1 ; i <= n ; i++)
{
scanf("%lld" , &a[i]);
}
sort(a+1 , a+n+1);
for(int i = 1 ; i <= n ; i++)
{
sum1[i] = sum1[i-1] + a[i];
}
for(int i = n ; i >= 1 ; i--)
{
sum2[i] = sum2[i+1] + a[i];
}
ll a = k - 2 , b = a , ans = 0;
for(int i = n - k + 1 , j = k ; i >= 1 ; i-- , j++ , a++)
{
ans = (ans%mod + (sum2[j] - sum1[i])%mod * C(a , b))%mod;
}
cout << ans << endl ;
return 0 ;
}
标签:排序 ons name 最小 题意 inf 最小值 组合 amp
原文地址:https://www.cnblogs.com/nonames/p/12190089.html