QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#843082 | #9967. Imbalanced Teams | ucup-team4435# | WA | 0ms | 3764kb | C++20 | 7.8kb | 2025-01-04 16:42:09 | 2025-01-04 16:42:16 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
#define all(a) begin(a), end(a)
#define len(a) int((a).size())
/*
! WARNING: MOD must be prime if you use division or .inv().
! WARNING: 2 * (MOD - 1) must be smaller than INT_MAX
* Use .value to get the stored value.
*/
template<typename T>
int normalize(T value, int mod) {
if (value < -mod || value >= 2 * mod) value %= mod;
if (value < 0) value += mod;
if (value >= mod) value -= mod;
return value;
}
template<int mod>
struct static_modular_int {
static_assert(mod - 2 <= std::numeric_limits<int>::max() - mod, "2(mod - 1) <= INT_MAX");
using mint = static_modular_int<mod>;
int value;
static_modular_int() : value(0) {}
static_modular_int(const mint &x) : value(x.value) {}
template<typename T, typename U = std::enable_if_t<std::is_integral<T>::value>>
static_modular_int(T value) : value(normalize(value, mod)) {}
static constexpr int get_mod() {
return mod;
}
template<typename T>
mint power(T degree) const {
mint prod = 1, a = *this;
for (; degree > 0; degree >>= 1, a *= a)
if (degree & 1)
prod *= a;
return prod;
}
mint inv() const {
return power(mod - 2);
}
mint& operator=(const mint &x) {
value = x.value;
return *this;
}
mint& operator+=(const mint &x) {
value += x.value;
if (value >= mod) value -= mod;
return *this;
}
mint& operator-=(const mint &x) {
value -= x.value;
if (value < 0) value += mod;
return *this;
}
mint& operator*=(const mint &x) {
value = int64_t(value) * x.value % mod;
return *this;
}
mint& operator/=(const mint &x) {
return *this *= x.inv();
}
friend mint operator+(const mint &x, const mint &y) {
return mint(x) += y;
}
friend mint operator-(const mint &x, const mint &y) {
return mint(x) -= y;
}
friend mint operator*(const mint &x, const mint &y) {
return mint(x) *= y;
}
friend mint operator/(const mint &x, const mint &y) {
return mint(x) /= y;
}
mint& operator++() {
++value;
if (value == mod) value = 0;
return *this;
}
mint& operator--() {
--value;
if (value == -1) value = mod - 1;
return *this;
}
mint operator++(int) {
mint prev = *this;
value++;
if (value == mod) value = 0;
return prev;
}
mint operator--(int) {
mint prev = *this;
value--;
if (value == -1) value = mod - 1;
return prev;
}
mint operator-() const {
return mint(0) - *this;
}
bool operator==(const mint &x) const {
return value == x.value;
}
bool operator!=(const mint &x) const {
return value != x.value;
}
bool operator<(const mint &x) const {
return value < x.value;
}
template<typename T>
explicit operator T() {
return value;
}
friend std::istream& operator>>(std::istream &in, mint &x) {
std::string s;
in >> s;
x = 0;
bool neg = s[0] == '-';
for (const auto c : s)
if (c != '-')
x = x * 10 + (c - '0');
if (neg)
x *= -1;
return in;
}
friend std::ostream& operator<<(std::ostream &out, const mint &x) {
return out << x.value;
}
static int primitive_root() {
if constexpr (mod == 1'000'000'007)
return 5;
if constexpr (mod == 998'244'353)
return 3;
if constexpr (mod == 786433)
return 10;
static int root = -1;
if (root != -1)
return root;
std::vector<int> primes;
int value = mod - 1;
for (int i = 2; i * i <= value; i++)
if (value % i == 0) {
primes.push_back(i);
while (value % i == 0)
value /= i;
}
if (value != 1)
primes.push_back(value);
for (int r = 2;; r++) {
bool ok = true;
for (auto p : primes)
if ((mint(r).power((mod - 1) / p)).value == 1) {
ok = false;
break;
}
if (ok)
return root = r;
}
}
};
constexpr int MOD = 1'000'000'007;
// constexpr int MOD = 998'244'353;
using mint = static_modular_int<MOD>;
/*
! WARNING: MOD must be prime.
* Define modular int class above it.
* No need to run any init function, it dynamically resizes the data.
*/
namespace combinatorics {
std::vector<mint> fact_, ifact_, inv_;
void resize_data(int size) {
if (fact_.empty()) {
fact_ = {mint(1), mint(1)};
ifact_ = {mint(1), mint(1)};
inv_ = {mint(0), mint(1)};
}
for (int pos = fact_.size(); pos <= size; pos++) {
fact_.push_back(fact_.back() * mint(pos));
inv_.push_back(-inv_[MOD % pos] * mint(MOD / pos));
ifact_.push_back(ifact_.back() * inv_[pos]);
}
}
struct combinatorics_info {
std::vector<mint> &data;
combinatorics_info(std::vector<mint> &data) : data(data) {}
mint operator[](int pos) {
if (pos >= static_cast<int>(data.size())) {
resize_data(pos);
}
return data[pos];
}
} fact(fact_), ifact(ifact_), inv(inv_);
// From n choose k.
// O(max(n)) in total.
mint choose(int n, int k) {
if (n < k || k < 0 || n < 0) {
return mint(0);
}
return fact[n] * ifact[k] * ifact[n - k];
}
// From n choose k.
// O(min(k, n - k)).
mint choose_slow(int64_t n, int64_t k) {
if (n < k || k < 0 || n < 0) {
return mint(0);
}
k = std::min(k, n - k);
mint result = 1;
for (int i = k; i >= 1; i--) {
result *= (n - i + 1);
result *= inv[i];
}
return result;
}
// Number of balanced bracket sequences with n open and m closing brackets.
mint catalan(int n, int m) {
if (m > n || m < 0) {
return mint(0);
}
return choose(n + m, m) - choose(n + m, m - 1);
}
// Number of balanced bracket sequences with n open and closing brackets.
mint catalan(int n) {
return catalan(n, n);
}
} // namespace combinatorics
using namespace combinatorics;
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n, k;
cin >> n >> k;
vector<int> a(n);
for (auto &x : a) {
cin >> x;
}
sort(all(a));
int p1 = k - 1;
int p2 = n - k;
cout << accumulate(a.begin() + p2, a.end(), 0ll) - accumulate(a.begin(), a.begin() + p1 + 1, 0ll) << ' ';
if (a[0] == a.back()) {
cout << choose(n, 2 * k) * choose(2 * k, k) / 2 << '\n';
return 0;
}
int l1 = 0;
while (l1 > 0 && a[l1 - 1] == a[p1]) {
l1--;
}
int r2 = p2;
while (r2 < n && a[r2] == a[p2]) {
r2++;
}
if (a[p1] == a[p2]) {
int cnt1 = p1 - l1 + 1;
int cnt2 = r2 - p2;
cout << choose(r2 - l1, cnt1 + cnt2) * choose(cnt1 + cnt2, cnt1) << '\n';
} else {
int r1 = p1;
while (a[r1] == a[p1]) {
r1++;
}
int l2 = p2;
while (a[l2 - 1] == a[p2]) {
l2--;
}
cout << choose(r1 - l1, p1 - l1 + 1) * choose(r2 - l2, r2 - p2) << '\n';
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3760kb
input:
6 2 2 5 7 2 5 2
output:
8 6
result:
ok 2 number(s): "8 6"
Test #2:
score: 0
Accepted
time: 0ms
memory: 3764kb
input:
5 2 1 1 1 1 1
output:
0 15
result:
ok 2 number(s): "0 15"
Test #3:
score: 0
Accepted
time: 0ms
memory: 3544kb
input:
2 1 1 1
output:
0 1
result:
ok 2 number(s): "0 1"
Test #4:
score: 0
Accepted
time: 0ms
memory: 3548kb
input:
2 1 1 2
output:
1 1
result:
ok 2 number(s): "1 1"
Test #5:
score: 0
Accepted
time: 0ms
memory: 3724kb
input:
10 4 3 3 1 2 4 6 2 4 4 1
output:
12 1
result:
ok 2 number(s): "12 1"
Test #6:
score: 0
Accepted
time: 0ms
memory: 3588kb
input:
14 3 57 57 57 57 57 57 57 57 57 57 57 57 57 57
output:
0 30030
result:
ok 2 number(s): "0 30030"
Test #7:
score: -100
Wrong Answer
time: 0ms
memory: 3760kb
input:
13 5 858336 900782 858336 900782 900782 858336 900782 858336 858336 858336 858336 858336 52093
output:
976027 504
result:
wrong answer 2nd numbers differ - expected: '280', found: '504'