Problem p02804 (C++)

Buggy submission (status: Time Limit Exceeded):
/* #region Head */

#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pll = pair<ll, ll>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vd = vector<double>;
using vvd = vector<vd>;
using vs = vector<string>;
using vvs = vector<vs>;

#define REP(i, m, n) for (ll i = (m), i##_len = (ll)(n); i < i##_len; ++(i))
#define REPM(i, m, n) for (ll i = (m), i##_max = (ll)(n); i <= i##_max; ++(i))
#define REPR(i, m, n) for (ll i = (m), i##_min = (ll)(n); i >= i##_min; --(i))
#define REPD(i, m, n, d)                                                       \
  for (ll i = (m), i##_len = (ll)(n); i < i##_len; i += (d))
#define REPMD(i, m, n, d)                                                      \
  for (ll i = (m), i##_max = (ll)(n); i <= i##_max; i += (d))
#define REPI(itr, ds) for (auto itr = ds.begin(); itr != ds.end(); itr++)
#define ALL(x) begin(x), end(x)
#define SIZE(x) ((ll)(x).size())

constexpr ll INF = 1'010'000'000'000'000'017LL;
constexpr ll MOD = 1'000'000'007LL; // 1e9 + 7
constexpr double EPS = 1e-12;
constexpr double PI = 3.14159265358979323846;

// vector入力
template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  for (T &x : vec)
    is >> x;
  return is;
}

// vector出力
template <typename T> ostream &operator<<(ostream &os, vector<T> &vec) {
  ll len = SIZE(vec);
  os << "{";
  for (int i = 0; i < len; i++)
    os << vec[i] << (i == len - 1 ? "" : ", ");
  os << "}";
  return os;
}

// pair入力
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &pair_var) {
  is >> pair_var.first >> pair_var.second;
  return is;
}

// pair出力
template <typename T, typename U>
ostream &operator<<(ostream &os, pair<T, U> &pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}

// map出力
template <typename T, typename U>
ostream &operator<<(ostream &os, map<T, U> &map_var) {
  os << "{";
  REPI(itr, map_var) {
    os << *itr;
    itr++;
    if (itr != map_var.end())
      os << ", ";
    itr--;
  }
  os << "}";
  return os;
}

// set 出力
template <typename T> ostream &operator<<(ostream &os, set<T> &set_var) {
  os << "{";
  REPI(itr, set_var) {
    os << *itr;
    itr++;
    if (itr != set_var.end())
      os << ", ";
    itr--;
  }
  os << "}";
  return os;
}

// dump
#define DUMPOUT cerr
void dump_func() { DUMPOUT << endl; }
template <class Head, class... Tail>
void dump_func(Head &&head, Tail &&...tail) {
  DUMPOUT << head;
  if (sizeof...(Tail) > 0) {
    DUMPOUT << ", ";
  }
  dump_func(move(tail)...);
}

// _max の終端．
template <class Head> ll _max(Head &&head) { return head; }
// 最大値を求める．max({}) の代わり．これにしないと vscode が壊れる．
template <class Head, class... Tail> ll _max(Head &&head, Tail &&...tail) {
  return max((ll)head, _max((tail)...));
}

// _min の終端．
template <class Head> ll _min(Head &&head) { return head; }
// 最小値を求める．min({}) の代わり．これにしないと vscode が壊れる．
template <class Head, class... Tail> ll _min(Head &&head, Tail &&...tail) {
  return min((ll)head, _min((tail)...));
}

// chmax (更新「される」かもしれない値が前)
template <typename T, typename U, typename Comp = less<>>
bool chmax(T &xmax, const U &x, Comp comp = {}) {
  if (comp(xmax, x)) {
    xmax = x;
    return true;
  }
  return false;
}

// chmin (更新「される」かもしれない値が前)
template <typename T, typename U, typename Comp = less<>>
bool chmin(T &xmin, const U &x, Comp comp = {}) {
  if (comp(x, xmin)) {
    xmin = x;
    return true;
  }
  return false;
}

// container 内の最初の element のインデックスを探す
template <class Container>
ll indexof(const Container &container,
           const typename Container::value_type &element) {
  auto iter = find(container.begin(), container.end(), element);
  size_t index = distance(container.begin(), iter);
  if (index == container.size()) {
    index = -1;
  }
  return index;
}

// ローカル用
#define DEBUG_

#ifdef DEBUG_
#define DEB
#define dump(...)                                                              \
  DUMPOUT << "  " << string(#__VA_ARGS__) << ": "                              \
          << "[" << to_string(__LINE__) << ":" << __FUNCTION__ << "]" << endl  \
          << "    ",                                                           \
      dump_func(__VA_ARGS__)
#else
#define DEB if (false)
#define dump(...)
#endif

struct AtCoderInitialize {
  static constexpr int IOS_PREC = 15;
  static constexpr bool AUTOFLUSH = false;

  AtCoderInitialize() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    cout << fixed << setprecision(IOS_PREC);
    if (AUTOFLUSH)
      cout << unitbuf;
  }
} ATCODER_INITIALIZE;

/* #endregion */

// 自動で MOD を取る整数
struct mint {
  ll x;
  mint(ll x = 0) : x((x % MOD + MOD) % MOD) {}
  mint &operator+=(const mint a) {
    if ((x += a.x) >= MOD)
      x -= MOD;
    return *this;
  }
  mint &operator-=(const mint a) {
    if ((x += MOD - a.x) >= MOD)
      x -= MOD;
    return *this;
  }
  mint &operator*=(const mint a) {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint operator+(const mint a) const {
    mint res(*this);
    return res += a;
  }
  mint operator-(const mint a) const {
    mint res(*this);
    return res -= a;
  }
  mint operator*(const mint a) const {
    mint res(*this);
    return res *= a;
  }
  // O(log(t))
  mint pow(ll t) const {
    if (!t)
      return 1;
    mint a = pow(t >> 1); // ⌊t/2⌋ 乗
    a *= a;               // ⌊t/2⌋*2 乗
    if (t & 1)            // ⌊t/2⌋*2 == t-1 のとき
      a *= *this;         // ⌊t/2⌋*2+1 乗 => t 乗
    return a;
  }

  // for prime mod
  mint inv() const {
    return pow(MOD - 2); // オイラーの定理から， x^(-1) ≡ x^(p-2)
  }
  mint &operator/=(const mint a) { return (*this) *= a.inv(); }
  mint operator/(const mint a) const {
    mint res(*this);
    return res /= a;
  }
};

// mint 入力
istream &operator>>(istream &is, mint &x) {
  is >> x.x;
  return is;
}

// mint 出力
ostream &operator<<(ostream &os, mint x) {
  os << x.x;
  return os;
}

/* 二項係数計算用クラス． */
class Combinaion {
private:
  /* テーブルの大きさを規定する．(MAX)! まで計算できる． */
  static constexpr ll MAX = 1e6;
  /* 階乗を格納するテーブル．fac[n] := n! % MOD. */
  vector<mint> fac;
  /* 階乗の逆元を格納するテーブル．finv[n] := (fac[n])^(-1). */
  vector<mint> finv;

  /* 各種テーブルを初期化する． */
  void init(int n) {
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    REPM(i, 2, n) { fac[i] = fac[i - 1] * i; }
    finv[n] = fac[n].inv();
    REPR(i, n, 2) { finv[i - 1] = finv[i] * i; }
  }

public:
  /* コンストラクタ． */
  Combinaion(int n = MAX) : fac(n + 1), finv(n + 1) { init(n); }

  /* 二項係数 nCk % MOD を計算する． */
  mint operator()(ll n, ll k) const {
    assert(n < MAX);
    assert(k < MAX);
    if (n < k || n < 0 || k < 0)
      return 0;
    return fac[n] * finv[k] * finv[n - k];
  }
};

/**
Problem
 */
void solve() {
  ll n, k;
  cin >> n >> k;
  vll a(n, 0);
  cin >> a;
  sort(ALL(a));
  vector<mint> am(n);
  REP(i, 0, n) { am[i] = a[i]; }
  Combinaion c;

  mint ret = 0;
  REP(i, 0, n - k + 1)
  REP(j, i + k - 1, n) {
    mint temp = c(j - i - 1, k - 2) * (a[j] - a[i]);
    ret += temp;
    // dump(temp, ret);
  }
  cout << ret << endl;
}

/**
 * エントリポイント．
 * @return 0.
 */
int main() {
  solve();
  return 0;
}


Fixed submission:
/* #region Head */

#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pll = pair<ll, ll>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vd = vector<double>;
using vvd = vector<vd>;
using vs = vector<string>;
using vvs = vector<vs>;

#define REP(i, m, n) for (ll i = (m), i##_len = (ll)(n); i < i##_len; ++(i))
#define REPM(i, m, n) for (ll i = (m), i##_max = (ll)(n); i <= i##_max; ++(i))
#define REPR(i, m, n) for (ll i = (m), i##_min = (ll)(n); i >= i##_min; --(i))
#define REPD(i, m, n, d)                                                       \
  for (ll i = (m), i##_len = (ll)(n); i < i##_len; i += (d))
#define REPMD(i, m, n, d)                                                      \
  for (ll i = (m), i##_max = (ll)(n); i <= i##_max; i += (d))
#define REPI(itr, ds) for (auto itr = ds.begin(); itr != ds.end(); itr++)
#define ALL(x) begin(x), end(x)
#define SIZE(x) ((ll)(x).size())

constexpr ll INF = 1'010'000'000'000'000'017LL;
constexpr ll MOD = 1'000'000'007LL; // 1e9 + 7
constexpr double EPS = 1e-12;
constexpr double PI = 3.14159265358979323846;

// vector入力
template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  for (T &x : vec)
    is >> x;
  return is;
}

// vector出力
template <typename T> ostream &operator<<(ostream &os, vector<T> &vec) {
  ll len = SIZE(vec);
  os << "{";
  for (int i = 0; i < len; i++)
    os << vec[i] << (i == len - 1 ? "" : ", ");
  os << "}";
  return os;
}

// pair入力
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &pair_var) {
  is >> pair_var.first >> pair_var.second;
  return is;
}

// pair出力
template <typename T, typename U>
ostream &operator<<(ostream &os, pair<T, U> &pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}

// map出力
template <typename T, typename U>
ostream &operator<<(ostream &os, map<T, U> &map_var) {
  os << "{";
  REPI(itr, map_var) {
    os << *itr;
    itr++;
    if (itr != map_var.end())
      os << ", ";
    itr--;
  }
  os << "}";
  return os;
}

// set 出力
template <typename T> ostream &operator<<(ostream &os, set<T> &set_var) {
  os << "{";
  REPI(itr, set_var) {
    os << *itr;
    itr++;
    if (itr != set_var.end())
      os << ", ";
    itr--;
  }
  os << "}";
  return os;
}

// dump
#define DUMPOUT cerr
void dump_func() { DUMPOUT << endl; }
template <class Head, class... Tail>
void dump_func(Head &&head, Tail &&...tail) {
  DUMPOUT << head;
  if (sizeof...(Tail) > 0) {
    DUMPOUT << ", ";
  }
  dump_func(move(tail)...);
}

// _max の終端．
template <class Head> ll _max(Head &&head) { return head; }
// 最大値を求める．max({}) の代わり．これにしないと vscode が壊れる．
template <class Head, class... Tail> ll _max(Head &&head, Tail &&...tail) {
  return max((ll)head, _max((tail)...));
}

// _min の終端．
template <class Head> ll _min(Head &&head) { return head; }
// 最小値を求める．min({}) の代わり．これにしないと vscode が壊れる．
template <class Head, class... Tail> ll _min(Head &&head, Tail &&...tail) {
  return min((ll)head, _min((tail)...));
}

// chmax (更新「される」かもしれない値が前)
template <typename T, typename U, typename Comp = less<>>
bool chmax(T &xmax, const U &x, Comp comp = {}) {
  if (comp(xmax, x)) {
    xmax = x;
    return true;
  }
  return false;
}

// chmin (更新「される」かもしれない値が前)
template <typename T, typename U, typename Comp = less<>>
bool chmin(T &xmin, const U &x, Comp comp = {}) {
  if (comp(x, xmin)) {
    xmin = x;
    return true;
  }
  return false;
}

// container 内の最初の element のインデックスを探す
template <class Container>
ll indexof(const Container &container,
           const typename Container::value_type &element) {
  auto iter = find(container.begin(), container.end(), element);
  size_t index = distance(container.begin(), iter);
  if (index == container.size()) {
    index = -1;
  }
  return index;
}

// ローカル用
#define DEBUG_

#ifdef DEBUG_
#define DEB
#define dump(...)                                                              \
  DUMPOUT << "  " << string(#__VA_ARGS__) << ": "                              \
          << "[" << to_string(__LINE__) << ":" << __FUNCTION__ << "]" << endl  \
          << "    ",                                                           \
      dump_func(__VA_ARGS__)
#else
#define DEB if (false)
#define dump(...)
#endif

struct AtCoderInitialize {
  static constexpr int IOS_PREC = 15;
  static constexpr bool AUTOFLUSH = false;

  AtCoderInitialize() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    cout << fixed << setprecision(IOS_PREC);
    if (AUTOFLUSH)
      cout << unitbuf;
  }
} ATCODER_INITIALIZE;

/* #endregion */

// 自動で MOD を取る整数
struct mint {
  ll x;
  mint(ll x = 0) : x((x % MOD + MOD) % MOD) {}
  mint &operator+=(const mint a) {
    if ((x += a.x) >= MOD)
      x -= MOD;
    return *this;
  }
  mint &operator-=(const mint a) {
    if ((x += MOD - a.x) >= MOD)
      x -= MOD;
    return *this;
  }
  mint &operator*=(const mint a) {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint operator+(const mint a) const {
    mint res(*this);
    return res += a;
  }
  mint operator-(const mint a) const {
    mint res(*this);
    return res -= a;
  }
  mint operator*(const mint a) const {
    mint res(*this);
    return res *= a;
  }
  // O(log(t))
  mint pow(ll t) const {
    if (!t)
      return 1;
    mint a = pow(t >> 1); // ⌊t/2⌋ 乗
    a *= a;               // ⌊t/2⌋*2 乗
    if (t & 1)            // ⌊t/2⌋*2 == t-1 のとき
      a *= *this;         // ⌊t/2⌋*2+1 乗 => t 乗
    return a;
  }

  // for prime mod
  mint inv() const {
    return pow(MOD - 2); // オイラーの定理から， x^(-1) ≡ x^(p-2)
  }
  mint &operator/=(const mint a) { return (*this) *= a.inv(); }
  mint operator/(const mint a) const {
    mint res(*this);
    return res /= a;
  }
};

// mint 入力
istream &operator>>(istream &is, mint &x) {
  is >> x.x;
  return is;
}

// mint 出力
ostream &operator<<(ostream &os, mint x) {
  os << x.x;
  return os;
}

/* 二項係数計算用クラス． */
class Combinaion {
private:
  /* テーブルの大きさを規定する．(MAX)! まで計算できる． */
  static constexpr ll MAX = 1e6;
  /* 階乗を格納するテーブル．fac[n] := n! % MOD. */
  vector<mint> fac;
  /* 階乗の逆元を格納するテーブル．finv[n] := (fac[n])^(-1). */
  vector<mint> finv;

  /* 各種テーブルを初期化する． */
  void init(int n) {
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    REPM(i, 2, n) { fac[i] = fac[i - 1] * i; }
    finv[n] = fac[n].inv();
    REPR(i, n, 2) { finv[i - 1] = finv[i] * i; }
  }

public:
  /* コンストラクタ． */
  Combinaion(int n = MAX) : fac(n + 1), finv(n + 1) { init(n); }

  /* 二項係数 nCk % MOD を計算する． */
  mint operator()(ll n, ll k) const {
    assert(n < MAX);
    assert(k < MAX);
    if (n < k || n < 0 || k < 0)
      return 0;
    return fac[n] * finv[k] * finv[n - k];
  }
};

/**
Problem
 */
void solve() {
  ll n, k;
  cin >> n >> k;
  vll a(n, 0);
  cin >> a;
  sort(ALL(a));
  vector<mint> am(n);
  REP(i, 0, n) { am[i] = a[i]; }
  Combinaion c;

  mint ret = 0;
  // REP(i, 0, n - k + 1)
  // REP(j, i + k - 1, n)
  // {
  //     mint temp = c(j - i - 1, k - 2) * (a[j] - a[i]);
  //     ret += temp;
  //     // dump(temp, ret);
  // }
  REP(i, 0, n) {
    mint maxc = (i >= k - 1) ? c(i, k - 1) : 0;
    mint minc = (i <= n - k) ? c(n - i - 1, k - 1) : 0;
    ret += (maxc - minc) * a[i];
  }
  cout << ret << endl;
}

/**
 * エントリポイント．
 * @return 0.
 */
int main() {
  solve();
  return 0;
}