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# (.NET Core 3.1.201) (judge verdict: Wrong Answer)

using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;

class Program
{
    const string Yes = "Yes";
    const string No = "No";
    const char White = '.';
    const char Black = '#';
    const long Mod = 1000000007;

    static void Main(string[] args) {
        checked {
#if DEBUG
            MyDebugger.Test(process, "../TextFile1.txt");
            //TestCaseMaker.MakeTestCase1("../TextFile2.txt");
            //MyDebugger.Test(process, "../TextFile2.txt");
#else
            object ret = process(new StreamReader(Console.OpenStandardInput()));
            Console.WriteLine(ret);
#endif
        }
    }

    static object process(TextReader input) {
        var spl = input.ReadLine().Split(' ');
        var n = int.Parse(spl[0]);
        var k = int.Parse(spl[1]);

        var ary = ToIntArray(input.ReadLine(), n);

        Array.Sort(ary, (x,y) => Math.Abs(y) - Math.Abs(x));

        var sums = new List<int>();
        bool minus = false;

        for(int i=0; i<k; i++) {
            sums.Add(ary[i]);
            if(ary[i] < 0) minus = !minus;
        }

        if (minus) {
            //採用値で最も小さい正の値と負の値
            int i1 = -1;
            int i2 = -1;
            for(int i = k-1; i >= 0; i--) {
                var x = sums[i];
                if(i1 == -1 && x >= 0) i1 = i;
                if(i2 == -1 && x < 0) i2 = i;
                if(i1 != -1 && i2 != -1) break;
            }

            //未採用値で最も大きい正の値と負の値
            int j1 = -1;
            int j2 = -1;
            for (int i = k; i < n; i++) {
                var x = ary[i];
                if (j1 == -1 && x >= 0) j1 = i;
                if (j2 == -1 && x < 0) j2 = i;
                if (j1 != -1 && j2 != -1) break;
            }

            //負と正を入れ替え
            int swapI = -1;
            int swapJ = -1;
            long diff = long.MaxValue;
            if(i2 != -1 && j1 != -1) {
                diff = -(long)sums[i2] - (long)ary[j1];
                swapI = i2;
                swapJ = j1; 
            }
            //正と負を入れ替え
            if(i1 != -1 && j2 != -1) {
                long tmp = (long)sums[i1] + (long)ary[j2];
                if(tmp < diff) {
                    swapI = i1;
                    swapJ = j2;
                    diff = tmp;
                }
            }

            //できない場合はどうやっても負になる
            if(diff == long.MaxValue) {
                sums.Clear();
                for(int i=0; i<k; i++) {
                    var x = ary[n-i-1];
                    sums.Add(x);
                }
            } else {
                sums[swapI] = ary[swapJ];
            }
        }

        long sum = 1;
        foreach (var x in sums) {
            sum *= (long)x;
            sum %= Mod;
        }
        if(sum < 0) {
            while(sum < 0)
                sum = sum + Mod;
        }

        return sum;
    }

    static int[] ToIntArray(string strs, int n) {
        var ret = new int[n];
        if (n == 0) return ret;
        var spl = strs.Split(' ');
        for (int i = 0; i < n; i++)
            ret[i] = int.Parse(spl[i]);
        return ret;
    }
}