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# (Mono-mcs 6.8.0.105) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
class Program
{
	static void Main(string[] args)
	{
		string[] str = Console.ReadLine().Split();
		int N = int.Parse(str[0]);
		int K = int.Parse(str[1]);
		string[] str2 = Console.ReadLine().Split();
		var listA = new List<long>();
		var listB = new List<long>();
		var listC = new List<long>();
		var listAB = new List<long>();
		for(var i=0;i<N;i++){
			long a = long.Parse(str2[i]);
			if(a > 0){
				listA.Add(a);
				listAB.Add(a);
			} else if(a<0){
				listB.Add(a);
				listAB.Add(a);
			} else {
				listC.Add(a);
			}
		}
		listA.Sort((x,y)=>y.CompareTo(x));
		listB.Sort((x,y)=>y.CompareTo(x));
		listAB.Sort((x,y)=>Math.Abs(y).CompareTo(Math.Abs(x)));
		long ans = 0;
		long mod = (long)Math.Pow(10,9)+7;
		if(K <= listAB.Count){
			ans = 1;
			int ct = 0;
			long minP = 99999999999;
			long minM = 99999999999;
			for(var i=0;i<K;i++){
				if(listAB[i] > 0){
					ans = ans * listAB[i] % mod;
					minP = Math.Min(minP,listAB[i]);
				} else {
					ans = ans * -listAB[i] % mod;
					minM = Math.Min(minM,-listAB[i]);
					ct++;
				}
			}
			bool flag = false;
			long ans1 = ans;
			long ans2 = ans;
			long a3 = -1;
			long a4 = -1;
			if(ct % 2 == 1){
				for(var i=K;i<listAB.Count;i++){
					if(listAB[i] > 0){
						a3 = Math.Max(a3,listAB[i]);
					} else {
						a4 = Math.Max(a4,-listAB[i]);
					}
				}
				if(minP == 99999999999){
					if(a3 == -1 && a4 == -1){
						if(listC.Count > 0){
							ans = 0;
						} else {
                          ans = (-ans + mod) % mod;
                        }
					} else if(a3 == -1){
						if(listC.Count>0){
							ans = 0;
						} else {
							ans = 1;
							for(var i=listAB.Count-1;i>=listAB.Count-K;i--){
								ans = ans * (-listAB[i]) % mod;
							}
							ans = (-ans + mod) % mod;
						}
					} else {
						ans = ans * a3 % mod;
						ans = ans * Mpow(minM,mod-2,mod) % mod;
					}
				} else {
					if(a3 == -1 && a4 == -1){
						if(listC.Count > 0){
							ans = 0;
						} else {
                          ans = (-ans + mod) % mod;
						}
					} else if(a3 == -1){
						ans = ans * a4 % mod;
						ans = ans * Mpow(minP,mod-2,mod) % mod;
					} else if(a4 == -1){
						ans = ans * a3 % mod;
						ans = ans * Mpow(minM,mod-2,mod) % mod;
					} else {
						if(minP * a3 > minM * a4){
							ans = ans * a3 % mod;
							ans = ans * Mpow(minM,mod-2,mod) % mod;
						} else {
							ans = ans * a4 % mod;
							ans = ans * Mpow(minP,mod-2,mod) % mod;
						}
					}
				}
			}
		}
		Console.WriteLine((ans+mod)%mod);
	}
	public static long Mpow(long x,long n,long m)
	{
		long ans = 1;
		while(n > 0){
			if(n % 2 == 1){
				ans = ans * x % m;
				n -= 1;
			}
			x = x * x % m;
			n /= 2;
		}
		return ans;
	}
}