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.Linq;
using static System.Math;
using System.Collections.Generic;
using Li = System.Collections.Generic.List<int>;
using Ll = System.Collections.Generic.List<long>;

namespace AtCoder0705
{
	class Program
	{
		static void Main(string[] args)
		{
			E();
		}

		private static void E()
		{
			const long mod = 1000000007;
			var ints = ReadInts();
			var k = ints[1];
			var a = ReadLongs();
			var positive = a.Where(x => x > 0).ToArray();
			var negative = a.Where(x => x < 0).ToArray();
			Array.Sort(positive);
			Array.Sort(negative);

			var zeroesCount = a.Length - positive.Length - negative.Length;
			if (positive.Length + negative.Length < k || (k == positive.Length + negative.Length && negative.Length % 2 == 1))
			{
				Console.WriteLine(0);
				return;
			}

			if (k == a.Length)
			{
				var res = a.Aggregate((x, y) => (x * y) % mod);
				Console.WriteLine((res + mod) % mod);
				return;
			}

			if (positive.Length == 0)
			{
				if (k % 2 == 1 && zeroesCount > 0)
				{
					Console.WriteLine(0);
					return;
				}

				if (k % 2 == 1)
				{
					var res = negative.Reverse().Take(k).Aggregate((x, y) => (x * y) % mod);
					Console.WriteLine((res + mod) % mod);
					return;
				}

				var resa = negative.Take(k).Aggregate((x, y) => (x * y) % mod);
				Console.WriteLine((resa + mod) % mod);
				return;
			}

			//sprawdzic czy musi byc ujemne
			//ujemne musi byc wtedy gdy musimy wziac nieparzysta liczbe ujemnych
			//tylko jezeli albo jest 0 dodatnich, albo trzeba wziac wszystko

			var absa = a.Select(x => new IntPair((int)x, Abs((int)x))).OrderByDescending(p => p.Second).ToArray();
			var countLess = absa.Take(k).Count(p => p.First < 0);
			countLess = countLess - countLess % 2;
			var countMore =k - countLess;
			long val = 1;
			var indLess = 0;
			var indMore = 0;
			var ind = 0;
			while (indLess < countLess || indMore < countMore)
			{
				if (absa[ind].First < 0 && indLess < countLess)
				{
					val *= absa[ind].Second;
					val %= mod;
					indLess++;
				}
				else if (absa[ind].First > 0 && indMore < countMore)
				{
					val *= absa[ind].Second;
					val %= mod;
					indMore++;
				}
				ind++;
			}

			Console.WriteLine(val);
		}

		private static void D()
		{
			var n = int.Parse(Console.ReadLine());
			var a = ReadLongs();
			Array.Sort(a);
			var bigger = a.Skip(a.Length / 2).ToArray();
			var sumB = bigger.Sum();
			long result = 2 * sumB - bigger[bigger.Length - 1] - (a.Length % 2 == 0 ? 0 : bigger[0]);

			Console.WriteLine(result);
		}

		static int[] bestPerm;
		static Li besC;

		private static long SolveDBrutal(int[] a)
		{
			var permutations = GetPermutations(a);
			long score = 0;

			foreach (var p in permutations)
			{
				var current = new Li { p[0] };
				SolveDBrutalRec(p, current, 0, ref score);
			}

			return score;
		}

		private static void SolveDBrutalRec(int[] p, Li current, long score, ref long bestScore)
		{
			if (current.Count == p.Length)
			{
				if (score > bestScore)
				{
					besC = current.ToList();
					bestPerm = p;
					bestScore = score;
				}
				return;
			}

			for (int i = 0; i < current.Count; i++)
			{
				current.Insert(i, p[current.Count]);
				var left = current[(i - 1 + current.Count) % current.Count];
				var right = current[(i + 1) % current.Count];
				var scoreL = score + Min(left, right);
				SolveDBrutalRec(p, current, scoreL, ref bestScore);
				current.RemoveAt(i);
			}
		}

		public static List<int[]> GetPermutations(int[] list)
		{
			int x = list.Length - 1;
			var result = new List<int[]>();
			GetPermutations(list, result, 0, x);
			return result;
		}

		private static void GetPermutations(int[] list, List<int[]> result, int k, int m)
		{
			if (k == m)
				result.Add(list.ToArray());
			else
				for (int i = k; i <= m; i++)
				{
					Swap(ref list[k], ref list[i]);
					GetPermutations(list, result, k + 1, m);
					Swap(ref list[k], ref list[i]);
				}
		}

		public static void Swap<T>(ref T a, ref T b)
		{
			T t = a;
			a = b;
			b = t;
		}

		private static void A()
		{
			var n = int.Parse(Console.ReadLine());
			Console.WriteLine((1000 - n % 1000) % 1000);
		}

		private static void B()
		{
			var n = int.Parse(Console.ReadLine());
			var strs = Enumerable.Range(0, n).Select(x => Console.ReadLine()).ToArray().GroupBy(x => x).Select(g => Tuple.Create(g.Key, g.Count())).ToArray();
			var ac = strs.Where(x => x.Item1 == "AC").Select(x => x.Item2).FirstOrDefault();
			var wa = strs.Where(x => x.Item1 == "WA").Select(x => x.Item2).FirstOrDefault();
			var tle = strs.Where(x => x.Item1 == "TLE").Select(x => x.Item2).FirstOrDefault();
			var re = strs.Where(x => x.Item1 == "RE").Select(x => x.Item2).FirstOrDefault();

			Console.WriteLine($"AC x {ac}");
			Console.WriteLine($"WA x {wa}");
			Console.WriteLine($"TLE x {tle}");
			Console.WriteLine($"RE x {re}");
		}


		private static void C()
		{
			var ints = ReadInts();
			var h = ints[0];
			var w = ints[1];
			var k = ints[2];

			var ar = Enumerable.Range(0, h).Select(x => Console.ReadLine().Select(c => c == '#').ToArray()).ToArray();
			var rowCounts = ar.Select(x => x.Count(y => y)).ToArray();
			var columnCounts = Enumerable.Range(0, w).Select(i => Enumerable.Range(0, h).Count(j => ar[j][i])).ToArray();

			var countResult = 0;
			for (int i = 0; i < 1 << (h + w); i++)
			{
				var arCopy = ar.Select(x => x.ToArray()).ToArray();
				for (int j = 0; j < h; j++)
					if ((i & (1 << j)) != 0)
						for (int l = 0; l < w; l++)
							arCopy[j][l] = false;

				for (int j = h; j < w + h; j++)
					if ((i & (1 << j)) != 0)
						for (int l = 0; l < h; l++)
							arCopy[l][j - h] = false;

				var c = arCopy.Sum(x => x.Count(y => y));
				if (c == k)
					countResult++;
			}

			Console.WriteLine(countResult);
		}

		private static int[] ReadInts() => Console.ReadLine().Split().Select(x => int.Parse(x)).ToArray();
		private static long[] ReadLongs() => Console.ReadLine().Split().Select(x => long.Parse(x)).ToArray();

	}

	public struct IntPair
	{
		public int First;
		public int Second;

		public IntPair(string s)
		{
			var split = s.Split();
			First = int.Parse(split[0]);
			Second = int.Parse(split[1]);
		}

		public IntPair(int first, int second)
		{
			First = first;
			Second = second;
		}

		public static bool operator ==(IntPair p1, IntPair p2) => p1.First == p2.First && p1.Second == p2.Second;
		public static bool operator !=(IntPair p1, IntPair p2) => p1.First != p2.First || p1.Second != p2.Second;
		public override string ToString() => $"{First} {Second}";
		public override bool Equals(object obj)
		{
			var p = obj as IntPair?;
			return p.HasValue && p.Value.First == First && p.Value.Second == Second;
		}

		public override int GetHashCode()
		{
			uint rol5 = ((uint)First << 5) | ((uint)First >> 27);
			return ((int)rol5 + First) ^ Second;
		}
	}
}