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 "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<ll, ll> Pll;
#define rep(begin, i, end) for (int i = begin; i < (int)(end); i++)
#define all(v) v.begin(), v.end()
const int MOD = 1000000007;

int main()
{
    ll N, K;
    cin >> N >> K;
    vector<Pll> A(N); // 正負の情報を持たせて入力

    // 負の数とそうでない数を数える
    ll c_p = 0, c_n = 0;
    rep(0, i, N)
    {
        ll a, b;
        cin >> a;
        if (a < 0)
        {
            c_n++;
            a *= -1;
            b = -1;
        }
        else
        {
            c_p++;
            b = 1;
        }

        A.at(i) = make_pair(a, b);
    }

    // N = K の自明なケース
    if (N == K)
    {
        ll ans = 1;
        rep(0, i, K)
        {
            ans *= A.at(i).first * A.at(i).second;
            if (ans < 0)
            {
                ans += MOD;
            }
            ans %= MOD;
        }
        cout << ans << endl;
        return 0;
    }

    sort(all(A));

    // Aiが全て奇数かつKが奇数の時のみ、答えが負になる
    if (c_n == N && (K % 2 != 0))
    {
        // 小さい順に掛け算していく
        ll ans = 1;
        rep(0, i, K)
        {
            ans *= A.at(i).first * A.at(i).second;
            while (ans < 0)
            {
                ans += MOD;
            }
            ans %= MOD;
        }
        cout << ans << endl;
    }
    // 最大値が正の数のとき
    else
    {
        ll ans = 1;
        // 絶対値が大きい順に掛け算していく
        reverse(all(A));

        // んだけど、貪欲に掛け算した時に負の数が何個なのかによって処理が変わるので、これを数える
        // ついでにあとで必要なので、K個の中に含まれる最小の正の数、負の数の添字を調べておく
        ll num_n = 0, last_p = 0, last_n = 0;
        rep(0, i, K)
        {
            if (A.at(i).second == -1)
            {
                num_n++;
                last_n = i;
            }
            else
            {
                last_p = i;
            }
        }

        // 負の数が偶数個なら、貪欲に掛け算すればok
        if (num_n % 2 == 0)
        {
            rep(0, i, K)
            {
                ans *= A.at(i).first;
                ans %= MOD;
            }
            cout << ans << endl;
        }
        // 負の数が奇数個の場合どうしよう？
        else
        {
            // かける負の数を適切に増やした数と減らした数のどちらかが最大値になるはず
            ll mul1 = 1, mul2 = 1;
            ll count = 0, flag = 0;

            // どっちが大きいのか比較するための変数
            ll num1 = 0, num2 = 0;

            // かける負の数を減らしてみよう
            rep(0, i, N)
            {
                // 減らすのは絶対値が一番小さい負の数
                if (i == last_n)
                {
                    flag = 1;
                    continue;
                }
                // これ以降は正の数しかかけません
                if (flag == 1 && A.at(i).second == -1)
                {
                    continue;
                }

                count++;
                mul1 *= A.at(i).first;
                mul1 %= MOD;

                // K個をかけ終わったらbreak
                if (count == K)
                {
                    num1 = A.at(i).first * A.at(last_p).first;
                    break;
                }
            }

            // かける正の数を減らしてみよう
            flag = 0;
            count = 0;
            rep(0, i, N)
            {
                // 減らすのは一番小さい正の数
                if (i == last_p)
                {
                    flag = 1;
                    continue;
                }
                // これ以降は負の数しかかけません
                if (flag == 1 && A.at(i).second == -1)
                {
                    continue;
                }

                count++;
                mul2 *= A.at(i).first;
                mul2 %= MOD;

                // K個をかけ終わったらbreak
                if (count == K)
                {
                    num2 = A.at(i).first * A.at(last_n).first;
                    break;
                }
            }

            if (num1 > num2)
            {
                ans = mul1;
            }
            else
            {
                ans = mul2;
            }

            cout << ans << endl;
        }
    }
}