数学--数论-- AtCoder Beginner Contest 151(组合数+数学推导)好题(๑•̀ㅂ•́)و✧

在这里插入图片描述
在这里插入图片描述
思路统计最大值出现的次数,和最小值出现的次数。虽然是每次都是MAX-MIN,我们先求MAX的和,然后再求MIN的和,做差。
这次代码写的真的很漂亮
题目地址:

#include <bits/stdc++.h>
using namespace std;
template <typename t>
void read(t &x)
{
    char ch = getchar();
    x = 0;
    t f = 1;
    while (ch < '0' || ch > '9')
        f = (ch == '-' ? -1 : f), ch = getchar();
    while (ch >= '0' && ch <= '9')
        x = x * 10 + ch - '0', ch = getchar();
    x *= f;
}
//---------------https://lunatic.blog.csdn.net/-------------------//
#define wi(n) printf("%d ", n)
#define wl(n) printf("%lld ", n)
#define rep(m, n, i) for (int i = m; i < n; ++i)
#define rrep(m, n, i) for (int i = m; i > n; --i)
#define P puts(" ")
typedef long long ll;
#define MOD 1000000007
#define mp(a, b) make_pair(a, b)
#define N 100005
#define fil(a, n) rep(0, n, i) read(a[i])
ll power(ll a, ll b, ll p)
{
    ll ans = 1 % p;
    for (; b; b >>= 1)
    {
        if (b & 1)
            ans = ans * a % p;
        a = a * a % p;
    }
    return ans;
}
long long mm[500000];
void init(ll n, ll k)
{
    mm[1] = 1;
    for (ll i = 2; i <= n; i++)
    {
        mm[i] = ((mm[i - 1] * (k + i - 1)) % MOD * power(i - 1, MOD - 2, MOD)) % MOD;
        //cout<<mm[i]<<endl;
    }
}
ll a[N];
int main()
{
    int n, k;
    read(n), read(k);
    fil(a, n);
    sort(a, a + n);
    init(n - k + 2, k - 1);
    long long sum = 0;
    rrep(n - 1, k - 2, i)
        sum = (sum + (mm[i - k + 2] * (a[i] - a[n - i - 1]) % MOD) % MOD) % MOD;
    wl((sum + MOD) % MOD);
    P;
}
posted @ 2020-02-29 02:39  风骨散人  阅读(109)  评论(0编辑  收藏  举报