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;

			// 不正な入力は処理しない
			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 zeroList = 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 if (input == 0) {
					zeroList.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;
			}


			//zeroを選ばないといけない場合
			if (plusListSorted.Length + minusListSorted.Length < K) {
				Console.WriteLine(0);
				return;
			}



			//plusListSorted.Length + minusListSorted.Length >= Kが保証されている
			if (plusListSorted.Length==0) {//すべてminusの場合

				if (K %2 == 1) {
					if (zeroList.Count() > 0) {
						Console.WriteLine(0);
						return;
					}

					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;
			}

			if (plusListSorted.Length + minusListSorted.Length == K) {//K <Nなので、0が必ず一つはある

				if (minusListSorted.Length % 2 == 1) {
					Console.WriteLine(0);
					return;
				}
				long ans2 = 1;
				foreach (var item in plusListSorted) {
					ans2 *= item;
					ans2 %= _mod;
				}

				foreach (var item in minusListSorted) {
					ans2 *= item;
					ans2 %= _mod;
				}

				Console.WriteLine(ans2);
				return;

			}


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

		}

		private static long _mod = 1000000000 + 7;

		private	static long getMaxMultple(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 < minus && plus < plusList.Length ? plusList[plus + 1] * plusList[plus]:0;
				var change2 = 0 < plus && minus < minusList.Length ? minusList[minus + 1] * minusList[minus] :0;

			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();
		}
	}
}