Problem:
Score : 500 points

Problem Statement

Given are N integers A_1,\ldots,A_N.

We will choose exactly K of these elements. Find the maximum possible product of the chosen elements.

Then, print the maximum product modulo (10^9+7), using an integer between 0 and 10^9+6 (inclusive).

Constraints

1 \leq K \leq N \leq 2\times 10^5

|A_i| \leq 10^9

Input

Input is given from Standard Input in the following format:

N K
A_1 \ldots A_N

Output

Print the maximum product modulo (10^9+7), using an integer between 0 and 10^9+6 (inclusive).

Sample Input 1

4 2
1 2 -3 -4

Sample Output 1

12

The possible products of the two chosen elements are 2, -3, -4, -6, -8, and 12, so the maximum product is 12.

Sample Input 2

4 3
-1 -2 -3 -4

Sample Output 2

1000000001

The possible products of the three chosen elements are -24, -12, -8, and -6, so the maximum product is -6.

We print this value modulo (10^9+7), that is, 1000000001.

Sample Input 3

2 1
-1 1000000000

Sample Output 3

1000000000

The possible products of the one chosen element are -1 and 1000000000, so the maximum product is 1000000000.

Sample Input 4

10 10
1000000000 100000000 10000000 1000000 100000 10000 1000 100 10 1

Sample Output 4

999983200

Be sure to print the product modulo (10^9+7).

Solution in C++ (GCC 9.2.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>

const int64_t MOD = 1000000007;

class ModInt {
public:
    ModInt() 
      : val(0), mod(0) 
    {
    }

    ModInt(int64_t v, int64_t m) 
      : val(v % m), mod(m)
    {
    }

    inline int64_t getVal() const noexcept {
        return this->val;
    }

    inline int64_t getMod() const noexcept {
        return this->mod;
    }

    inline ModInt operator - () const noexcept {
        return this->val ? ModInt(this->mod - this->val, this->mod) : ModInt(0, this->mod);
    }

    inline ModInt operator + (const ModInt& r) const noexcept {
        return ModInt(*this) += r;
    }

    inline ModInt operator - (const ModInt& r) const noexcept {
        return ModInt(*this) -= r;
    }

    inline ModInt operator * (const ModInt& r) const noexcept {
        return ModInt(*this) *= r;
    }

    inline ModInt operator / (const ModInt& r) const noexcept {
        return ModInt(*this) /= r;
    }

    inline ModInt& operator += (const ModInt& r) noexcept {
        this->val += r.val;
        this->val %= this->mod;
        return *this;
    }

    inline ModInt& operator -= (const ModInt& r) noexcept {
        this->val -= r.val;
        if (this->val < 0) {
            this->val += this->mod;
        }
        return *this;
    }

    inline ModInt& operator *= (const ModInt& r) noexcept {
        this->val = this->val * r.val % this->mod;
        return *this;
    }

    inline ModInt& operator /= (const ModInt& r) noexcept {
        int64_t a = r.val, b = this->mod, u = 1, v = 0;
        while (b) {
            int64_t t = a / b;
            a -= t * b; std::swap(a, b);
            u -= t * v; std::swap(u, v);
        }
        this->val = this->val * u % this->mod;
        if (val < 0) {
            val += this->mod;
        }

        return *this;
    }

    inline bool operator == (const ModInt& r) const noexcept {
        return this->val == r.val;
    }

    inline bool operator != (const ModInt& r) const noexcept {
        return this->val != r.val;
    }

    friend std::ostream& operator << (std::ostream& os, const ModInt& x) noexcept {
        return os << x.val;
    }

private:
    int64_t val;
    int64_t mod;
};

ModInt modpow(int64_t a, int64_t n, int64_t mod) {
    ModInt ret(1, mod);
    ModInt ma(a, mod);
    while (n > 0) {
        if (n & 1) {
            ret *= ma;
        }
        ma *= ma;
        n >>= 1;
    }

    return ret;
}

ModInt modfact(int64_t n, int64_t mod) {
    static std::vector<ModInt> facts;
    if (n < (int64_t)(facts.size())) {
        return facts[n];
    } else {
        const int64_t org_size = facts.size();
        facts.resize(n + 1);
        for (int64_t i = org_size; i <= n; ++i) {
            facts[i] = ((i == 0) ? ModInt(1, mod) : facts[i-1] * ModInt(i, mod));
        }

        return facts[n];
    }
}

ModInt modconb(int64_t n, int64_t k, int64_t mod) {
    return modfact(n, mod) / (modfact(n-k, mod) * modfact(k, mod));
}

struct V {
    V(int64_t val) {
        if (val >= 0) {
            this->orig = val;
            this->abs = val;
        } else {
            this->orig = val;
            this->abs = -val;
        } 
    }

    int64_t orig;
    int64_t abs;
};

int main() {
    int N, K;
    std::cin >> N >> K;

    int64_t A[N];
    std::vector<int64_t> A_minus;
    std::vector<int64_t> A_plus;

    std::vector<V> vals;
    for (int i = 0; i < N; ++i) {
        std::cin >> A[i];
        
        vals.push_back(V(A[i]));

        if (A[i] < 0) {
            A_minus.push_back(A[i]);
        } else {
            A_plus.push_back(A[i]);
        }
    }

    std::sort(A_plus.begin(), A_plus.end(), std::greater<int64_t>());
    std::sort(A_minus.begin(), A_minus.end());

    std::sort(vals.begin(), vals.end(), [](const V& lhs, const V& rhs) {
        return (lhs.abs > rhs.abs);
    });
    
    int64_t last_minus = 0, last_plus = 0;
    size_t minus = 0, plus = 0;
    ModInt ans(1, MOD);
    for (int i = 0; i < K; ++i) {
        ans *= ModInt(vals[i].orig, MOD);

        if (vals[i].orig < 0) {
            ++minus;
            last_minus = vals[i].orig;
        } else {
            ++plus;
            last_plus= vals[i].orig;
        }
    }

    if (ans.getVal() >= 0 || K == N) {
        std::cout << ans << std::endl;
        return 0;
    }

    if (A_plus.size() == 0) {
        ModInt minus_ans(1, MOD);
        std::sort(A_minus.begin(), A_minus.end(), std::greater<int64_t>());
        for (int i = 0; i < K; ++i) {
            minus_ans *= ModInt(A_minus[i], MOD);
        }

        std::cout << MOD + minus_ans.getVal() << std::endl;
        return 0;
    }

    if (plus == A_plus.size()) {
        ModInt v2 = ans / ModInt(last_plus, MOD) * ModInt(A_minus[minus], MOD);
        std::cout << v2 << std::endl;
        return 0;
    } else if (minus == A_minus.size()) {
        ModInt v1 = -ans / ModInt(last_minus, MOD) * ModInt(A_plus[plus], MOD);
        std::cout << v1 << std::endl;

        return 0;
    }

    ModInt v1 = ans / ModInt(last_minus, MOD) * ModInt(A_plus[plus], MOD);
    ModInt v2 = ans / ModInt(last_plus, MOD) * ModInt(A_minus[minus], MOD);

    if (v1.getVal() > v2.getVal()) {
        std::cout << v1 << std::endl;
    } else {
        std::cout << v2 << std::endl;
    }

    return 0;
}