Language: C++

/**
  *  Author: dhruv_gheewala
  *  Problem: E - Multiplication 4
  *  Date:   03.09.2020
  *  Time:   17:30:27
**/

#if __has_include("debug.h")
    #include "debug.h"
#else
    #include<bits/stdc++.h>
    using namespace std;
    
    #define fundri 108
    #define debug(...) 1729
#endif

#define int int64_t
typedef pair<int, int> pii;
typedef vector<int> vi;

const bool testcases = false;
#define ff first
#define ss second
#define endl '\n'
#define all(s) s.begin(), s.end()

// if vector isn't soted then it will remove consecutive same elements
#define make_unique(vec) vec.erase(unique(all(vec)), vec.end())
#define test int TC = 1;if(testcases)cin >> TC;for(int tc = 1 ; tc <= TC ; tc++)solve(), fundri
#define sort_by(cont,expr) sort(all(cont),[&](const auto &lhs,const auto &rhs){return expr;})
// clears stdin
#define flush(ch) cin.ignore(std::numeric_limits<std::streamsize>::max(), ch) // default, EOF

int seed; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
inline int rnd(int l = 0, int r = INT_MAX) {return uniform_int_distribution<int>(l, r)(rng);}

inline bool in_range(int a, int l, int r) {return (a >= l && a <= r);}
template<typename H, typename ...T>void inp(H &head) {cin >> head;}
template<typename H, typename ...T>void inp(H &head, T &...tail) {cin >> head;inp(tail...);}
template<typename T>bool isPrime(T n) {for(T i = 2; i * i <= n; i++)if(n % i == 0)return false; return n >= 2;}
template<typename T>inline istream &operator >>(istream &in, vector<T> &a) {for(T &x : a)in >> x; return in;}
template<typename T, typename U>inline istream &operator >>(istream &in, pair<T, U> &a) {in >> a.ff >> a.ss; return in;}

void solve();
void fast_io();

int32_t main(int32_t argc, char **argv)
{
    fast_io();
    test;
    return 0;
}

template<typename T>
T inverse(T a, T m)
{
    T u, v, t;
    u = 0;
    v = 1;

    while(a != 0)
    {
        t = m / a;
        m -= t * a;
        swap(a, m);
        u -= t * v;
        swap(u, v);
    }

    assert(m == 1);
    return u;
}

template<typename T>
class Modular
{
    public:
        using Type = typename decay<decltype(T::value)>::type;

        constexpr Modular() : value() {}
        
        template<typename U>
        Modular(const U& x)
        {
            value = normalize(x);
        }

        template<typename U>
        static Type normalize(const U& x)
        {
            Type v;
            if(-mod() <= x && x < mod()) v = static_cast<Type>(x);
            else v = static_cast<Type>(x % mod());
            if(v < 0) v += mod();
            return v;
        }

        const Type& operator()() const {return value;}
        
        template<typename U>
        explicit operator U() const {return static_cast<U>(value);}
        constexpr static Type mod() {return T::value;}

        Modular& operator+=(const Modular& other)
        {
            if((value += other.value) >= mod()) 
                value -= mod(); 
            return *this;
        }
        
        Modular& operator-=(const Modular& other)
        {
            if((value -= other.value) < 0)
                value += mod();
            return *this;
        }

        template <typename U> Modular& operator+=(const U& other){return *this += Modular(other);}
        template <typename U> Modular& operator-=(const U& other){return *this -= Modular(other);}
        Modular& operator++(){return *this += 1;}
        Modular& operator--(){return *this -= 1;}
        Modular operator++(int32_t){Modular result(*this); *this += 1; return result;}
        Modular operator--(int32_t){ Modular result(*this); *this -= 1; return result;}
        Modular operator-() const{return Modular(-value);}

        template<typename U = T>
        typename enable_if<is_same<typename Modular<U>::Type, int32_t>::value, Modular>::type& operator*=(const Modular& rhs)
        {
            #ifdef _WIN32
                uint64_t x = static_cast<int64_t>(value) * static_cast<int64_t>(rhs.value);
                uint32_t xh = static_cast<uint32_t>(x >> 32), xl = static_cast<uint32_t>(x), d, m;
                asm(
                  "divl %4; \n\t"
                  : "=a" (d), "=d" (m)
                  : "d" (xh), "a" (xl), "r" (mod())
                  );
                value = m;
            #else
                value = normalize(static_cast<int64_t>(value) * static_cast<int64_t>(rhs.value));
            #endif
                return *this;
        }
        
        template<typename U = T>
        typename enable_if<is_same<typename Modular<U>::Type, int64_t>::value, Modular>::type& operator*=(const Modular& rhs)
        {
            int64_t q = static_cast<int64_t>(static_cast<long double>(value) * rhs.value / mod());
            value = normalize(value * rhs.value - q * mod());
            return *this;
        }
        
        template<typename U = T>
        typename enable_if<!is_integral<typename Modular<U>::Type>::value, Modular>::type& operator*=(const Modular& rhs)
        {
            value = normalize(value * rhs.value);
            return *this;
        }

        Modular& operator/=(const Modular& other){return *this *= Modular(inverse(other.value, mod()));}

        template<typename U>
        friend const Modular<U>& abs(const Modular<U>& v){return v;}

        template<typename U>
        friend bool operator==(const Modular<U>& lhs, const Modular<U>& rhs);

        template<typename U>
        friend bool operator<(const Modular<U>& lhs, const Modular<U>& rhs);

        template<typename U>
        friend std::istream& operator>>(std::istream& stream, Modular<U>& number);

    private:
        Type value;
};

template<typename T> bool operator==(const Modular<T>& lhs, const Modular<T>& rhs){return lhs.value == rhs.value;}
template<typename T, typename U> bool operator==(const Modular<T>& lhs, U rhs){return lhs == Modular<T>(rhs);}
template<typename T, typename U> bool operator==(U lhs, const Modular<T>& rhs){return Modular<T>(lhs) == rhs;}

template<typename T> bool operator!=(const Modular<T>& lhs, const Modular<T>& rhs){return !(lhs == rhs);}
template<typename T, typename U> bool operator!=(const Modular<T>& lhs, U rhs){return !(lhs == rhs);}
template<typename T, typename U> bool operator!=(U lhs, const Modular<T>& rhs){return !(lhs == rhs);}

template<typename T> bool operator<(const Modular<T>& lhs, const Modular<T>& rhs){return lhs.value < rhs.value;}

template<typename T> Modular<T> operator+(const Modular<T>& lhs, const Modular<T>& rhs){return Modular<T>(lhs) += rhs;}
template<typename T, typename U> Modular<T> operator+(const Modular<T>& lhs, U rhs){return Modular<T>(lhs) += rhs;}
template<typename T, typename U> Modular<T> operator+(U lhs, const Modular<T>& rhs){return Modular<T>(lhs) += rhs;}

template<typename T> Modular<T> operator-(const Modular<T>& lhs, const Modular<T>& rhs){return Modular<T>(lhs) -= rhs;}
template<typename T, typename U> Modular<T> operator-(const Modular<T>& lhs, U rhs){return Modular<T>(lhs) -= rhs;}
template<typename T, typename U> Modular<T> operator-(U lhs, const Modular<T>& rhs){return Modular<T>(lhs) -= rhs;}

template<typename T> Modular<T> operator*(const Modular<T>& lhs, const Modular<T>& rhs){return Modular<T>(lhs) *= rhs;}
template<typename T, typename U> Modular<T> operator*(const Modular<T>& lhs, U rhs){return Modular<T>(lhs) *= rhs;}
template<typename T, typename U> Modular<T> operator*(U lhs, const Modular<T>& rhs){return Modular<T>(lhs) *= rhs;}

template<typename T> Modular<T> operator/(const Modular<T>& lhs, const Modular<T>& rhs){return Modular<T>(lhs) /= rhs;}
template<typename T, typename U> Modular<T> operator/(const Modular<T>& lhs, U rhs){return Modular<T>(lhs) /= rhs;}
template<typename T, typename U> Modular<T> operator/(U lhs, const Modular<T>& rhs){return Modular<T>(lhs) /= rhs;}

template<typename T, typename U>
Modular<T> power(const Modular<T>& a, const U& b)
{
    assert(b >= 0);
    Modular<T> x = a, res = 1;
    U p = b;
    while(p > 0)
    {
        if(p & 1)
            res *= x;
        x *= x;
        p >>= 1;
    }
    return res;
}

template<typename T>
bool IsZero(const Modular<T>& number){return number() == 0;}

template<typename T>
string to_string(const Modular<T>& number){return to_string(number());}

template<typename T>
std::ostream& operator<<(std::ostream& stream, const Modular<T>& number){return stream << number();}

template<typename T>
std::istream& operator>>(std::istream& stream, Modular<T>& number)
{
    typename common_type<typename Modular<T>::Type, int64_t>::type x;
    stream >> x;
    number.value = Modular<T>::normalize(x);
    return stream;
}

/*
using ModType = int;

struct VarMod { static ModType value; };
ModType VarMod::value;
ModType& MOD = VarMod::value;
using Mint = Modular<VarMod>;
*/

constexpr int32_t MOD = 1e9 + 7;
using Mint = Modular<std::integral_constant<decay<decltype(MOD)>::type, MOD>>;
typedef vector<Mint> vMi;

vMi inv,inv_fact,fact;
void build_factorial(int maximum = 1e6)
{
    for(int i = 2 ; i * i <= MOD ; i++)
        assert(MOD % i);

    inv = {0, 1};
    fact = inv_fact = {1, 1};

    maximum = max(maximum, 1LL);
    inv.resize(maximum + 1);
    fact.resize(maximum + 1);
    inv_fact.resize(maximum + 1);

    for(int i = 2 ; i <= maximum ; i++)
    {
        inv[i] = inv[MOD % i] * (MOD - MOD / i);
        fact[i] = i * fact[i - 1];
        inv_fact[i] = inv[i] * inv_fact[i - 1];
    }
}

Mint choose(int n, int r)
{
    if(in_range(r, 0LL, n))
        return fact[n] * inv_fact[r] * inv_fact[n-r];
    return 0;
}

Mint inv_choose(int n, int r)
{
    assert(in_range(r, 0LL, n));
    return inv_fact[n] * fact[r] * fact[n - r];
}

Mint permute(int n, int r)
{
    if(in_range(r, 0LL, n))
        return fact[n] * inv_fact[n - r];
    return 0;
}

Mint inv_permute(int n, int r)
{
    assert(in_range(r, 0LL, n));
    return inv_fact[n] * fact[n - r];
}

const int mod = 1e9 + 7;
int mul(int a, int b) {return ((a % mod) * (b % mod)) % mod;}

void solve()
{
    int n, k;
    cin >> n >> k;
    vi a(n);
    cin >> a;

    int zero = 0;
    multiset<int, greater<int>> pos, neg;
    // multiset<int> cpos, cneg;
    for(int i = 0 ; i < n ; i++) {
        if(a[i] > 0)
            pos.insert(mul(a[i], 1));
        else if(a[i] < 0)
            neg.insert(mul(-a[i], 1));
        else
            zero++;
    }

    if(k + zero > n) {
        cout << 0 << endl;
        return;
    }
    
    Mint ans = 1;
    if(!pos.size()) {

        // only negs and k is odd => minimize our ans
        if(k % 2 == 1) {

            if(zero > 0) {
                cout << 0 << endl;
                return;
            }

            while(neg.size() > k)
                neg.erase(neg.begin());

            while(!neg.empty()) {
                // ans = mul(ans, *neg.begin());
                ans *= *neg.begin();
                neg.erase(neg.begin());
            }
            cout << ans << endl;
            return;
        }

        // only negs and k is even => maximize
        while(k > 0) {
            // ans = mul(ans, *neg.begin());
            ans *= *neg.begin();
            neg.erase(neg.begin());
            k--;
        }
        cout << ans << endl;
    }
    else if(!neg.size()) {

        // only pos numbers
        while(k > 0) {
            // ans = mul(ans, *pos.begin());
            ans *= *pos.begin();
            pos.erase(pos.begin());
            k--;
        }
        cout << ans << endl;
    }
    else
    {
        // for(int x : pos)
        //     cpos.insert(x);
        // for(int x : neg)
        //     cneg.insert(-x);

        if(k % 2 == 1) {
            // ans = mul(ans, *pos.begin());
            ans *= *pos.begin();
            pos.erase(pos.begin());
            k--;
        }

        while(k > 0 && pos.size() >= 2 && neg.size() >= 2) {
            int pfir = *pos.begin();
            pos.erase(pos.begin());
            int psec = *pos.begin();
            pos.erase(pos.begin());

            int nfir = *neg.begin();
            neg.erase(neg.begin());
            int nsec = *neg.begin();
            neg.erase(neg.begin());

            if(pfir * psec > nfir * nsec) {
                neg.insert(nfir);
                neg.insert(nsec);
                // ans = mul(ans, mul(pfir, psec));
                ans *= pfir;
                ans *= psec;
            }
            else {
                pos.insert(pfir);
                pos.insert(psec);
                // ans = mul(ans, mul(nfir, nsec));
                ans *= nfir;
                ans *= nsec;
            }
            k -= 2;
        }

        while(k > 0 && pos.size() >= 2) {
            int fir = *pos.begin();
            pos.erase(pos.begin());
            int sec = *pos.begin();
            pos.erase(pos.begin());

            // ans = mul(ans, mul(fir, sec));
            ans *= fir;
            ans *= sec;
            k -= 2;
        }

        while(k > 0 && neg.size() >= 2) {
            int fir = *neg.begin();
            neg.erase(neg.begin());
            int sec = *neg.begin();
            neg.erase(neg.begin());

            // ans = mul(ans, mul(fir, sec));
            ans *= fir;
            ans *= sec;
            k -= 2;
        }
        
        if(k > 0) {
            if(zero > 0)
                ans = 0;
            else {
                // ans = mul(ans, mul(*pos.begin(), *neg.begin()));
                ans *= *pos.begin();
                ans *= *neg.begin();
            }
        }
        cout << ans << endl;
    }
}

void fast_io()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

#ifdef DHRUV_GHEEWALA
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    freopen("debug.txt", "w", stderr);
#endif
}

Compiler output:
a.cc: In function 'void build_factorial(int64_t)':
a.cc:260:18: error: no matching function for call to 'max(int64_t&, long long int)'
  260 |     maximum = max(maximum, 1LL);
      |               ~~~^~~~~~~~~~~~~~
In file included from /usr/include/c++/14/algorithm:60,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:51,
                 from a.cc:11:
/usr/include/c++/14/bits/stl_algobase.h:257:5: note: candidate: 'template<class _Tp> constexpr const _Tp& std::max(const _Tp&, const _Tp&)'
  257 |     max(const _Tp& __a, const _Tp& __b)
      |     ^~~
/usr/include/c++/14/bits/stl_algobase.h:257:5: note:   template argument deduction/substitution failed:
a.cc:260:18: note:   deduced conflicting types for parameter 'const _Tp' ('long int' and 'long long int')
  260 |     maximum = max(maximum, 1LL);
      |               ~~~^~~~~~~~~~~~~~
/usr/include/c++/14/bits/stl_algobase.h:303:5: note: candidate: 'template<class _Tp, class _Compare> constexpr const _Tp& std::max(const _Tp&, const _Tp&, _Compare)'
  303 |     max(const _Tp& __a, const _Tp& __b, _Compare __comp)
      |     ^~~
/usr/include/c++/14/bits/stl_algobase.h:303:5: note:   candidate expects 3 arguments, 2 provided
In file included from /usr/include/c++/14/algorithm:61:
/usr/include/c++/14/bits/stl_algo.h:5706:5: note: candidate: 'template<class _Tp> constexpr _Tp std::max(initializer_list<_Tp>)'
 5706 |     max(initializer_list<_Tp> __l)
      |     ^~~
/usr/include/c++/14/bits/stl_algo.h:5706:5: note:   candidate expects 1 argument, 2 provided
/usr/include/c++/14/bits/stl_algo.h:5716:5: note: candidate: 'template<class _Tp, class _Compare> constexpr _Tp std::max(initializer_list<_Tp>, _Compare)'
 5716 |     max(initializer_list<_Tp> __l, _Compare __comp)
      |     ^~~
/usr/include/c++/14/bits/stl_algo.h:5716:5: note:   template argument deduction/substitution failed:
a.cc:260:18: note:   mismatched types 'std::initializer_list<_Tp>' and 'long int'
  260 |     maximum = max(maximum, 1LL);
      |               ~~~^~~~~~~~~~~~~~