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: Runtime Error)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AtCoder2 {
	class Program {
		static void Main(string[] args) {
		var inputArray = retreiveLongArray();
			var inputCount = 2;

			checked {


			// 不正な入力は処理しない
			if (inputArray.Length != inputCount) {
				Console.WriteLine("invalid input");
				return;
			}
			long N = inputArray[0];
			long K = inputArray[1];
			var Aarray = retreiveLongArray();

			var plusList = new List<long>();
			var minusList = new List<long>();

			for (int i = 0; i < N; i++) {

				var input = Aarray[i];
				if (input >= 0) {
					plusList.Add(input);
				}
				else {
					minusList.Add(-input);
				}

			}

			var plusListSorted = plusList.OrderByDescending(x => x).ToArray();
			var minusListSorted = minusList.OrderByDescending(x => x).ToArray();

			if (K==N) {//この場合はすべて×しかない
				long ans2 = 1;
				foreach (var item in plusListSorted) {
					ans2 *= item;
					ans2 %= _mod;
				}

				foreach (var item in minusListSorted) {
					ans2 *= item;
					ans2 %= _mod;
				}
				ans2 = minusListSorted.Length % 2 == 1 ? _mod-ans2 : ans2;
				Console.WriteLine(ans2);
				return;
			}


			if (plusListSorted.Length==0) {//すべてminusの場合

				if (K %2 == 1) {
					long ans2 = 1;
					for (int i = 0; i < K; i++) {
						ans2 *= minusListSorted[minusListSorted.Length - i - 1];
						ans2 %= _mod;
					}
					var finalAns = (_mod-ans2);
					Console.WriteLine(finalAns);
					return;
				}
				else {
					long ans2 = 1;
					for (int i = 0; i < K; i++) {
						ans2 *= minusListSorted[i];
						ans2 %= _mod;
					}
					Console.WriteLine(ans2);
					return;
				}
			}

			if (minusListSorted.Length == 0) {//すべてplusの場合
				long ans2 = 1;
				for (int i = 0; i < K; i++) {
					ans2 *= plusListSorted[i];
					ans2 %= _mod;
				}
				Console.WriteLine(ans2);
				return;
			}

			//答えの出力
			var ans = getMaxMultple2(K, plusListSorted, minusListSorted);
			Console.WriteLine(ans);
			}

		}

		private static long _mod = 1000000000 + 7;

		private	static long getMaxMultple(long K, long[] plusList, long[] minusList) {
			//絶対値の大きいものからかけておけばよい

			long answer = 1;

			var pair = new List<long>();

			if (K %2 == 1) {
				answer *= plusList[0];
				plusList = plusList.Where((x, index) => index != 0).ToArray();
				K--;
			}
			var p = 0;
			while (p +1 < plusList.Count()) {
				pair.Add(plusList[p] * plusList[p + 1]);
				p += 2;
			}

			var m = 0;

			while (m +1 < minusList.Count()) {
				pair.Add(minusList[m] * minusList[m + 1]);
				m += 2;
			}

			var sortedPair = pair.OrderByDescending(x => x).ToArray();

			for (int i = 0; i < K/2; i++) {
				answer *= sortedPair[i];
				answer %= _mod;
			}
			return answer;
		}

		private static long getMaxMultple2(long K, long[] plusList, long[] minusList) {
			//絶対値の大きいものからかけておけばよい
			long plus = 0;
			long minus = 0;
			long answer = 1;
			var seihu = true;
			for (int i = 0; i < K; i++) {

				//minusが残り0の場合、常にplusをかけるようにする
				if (minusList.Length - minus < 1) {
					plus++;
					continue;
				}

				//plusが残り0の場合、常にminusをかけるようにする
				if (plusList.Length - plus <= 1) {
					minus++;
					seihu = !seihu;
					continue;
				}

				var plusNum = plusList[plus];
				var minusNum = minusList[minus];

				if (plusNum >= minusNum) {
					plus++;
				}
				else {
					minus++;
					seihu = !seihu;
				}
			}

			if (seihu) {//正の場合
				for (int i = 0; i < plus; i++) {
					answer *= plusList[i];
					answer %= _mod;
				}
				for (int i = 0; i < minus; i++) {
					answer *= minusList[i];
					answer %= _mod;
				}
				return answer;
			}
			//マイナスの場合
			var change = 0 < plus && minus < minusList.Length ? plusList[plus] /(double)minusList[minus - 1] : -1;
			//plusを足して、マイナスを除く場合
			//minusを足して、plusを除く場合
			var change2 = 0 < minus && plus < plusList.Length ? minusList[minus] / (double)plusList[plus - 1] : -1;

			if (change < change2) {
				long answerA = 1;

				for (int i = 0; i < plus - 1; i++) {
					answerA *= plusList[i];
					answerA %= _mod;
				}
				for (int i = 0; i < minus + 1; i++) {
					answerA *= minusList[i];
					answerA %= _mod;
				}
				return answerA;
			}
			else {
				long answerB = 1;
				for (int i = 0; i < plus + 1; i++) {
					answerB *= plusList[i];
					answerB %= _mod;
				}
				for (int i = 0; i < minus - 1; i++) {
					answerB *= minusList[i];
					answerB %= _mod;
				}
				return answerB;
			}

		}

		/// <summary>
		/// スペースで区切られた文字列配列の入力を受け取る
		/// </summary>
		/// <returns></returns>
		private static string[] retreiveStringArray() {
			var inputArray = Console.ReadLine().Split(' ');
			return inputArray;
		}

		/// <summary>
		/// スペースで区切られた整数配列の入力を受け取る
		/// </summary>
		/// <returns></returns>
		private static long[] retreiveLongArray() {
			var inputArray = Console.ReadLine().Split(' ');
			var longArray = inputArray.Select(s => long.Parse(s));
			return longArray.ToArray();
		}
	}
}