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: Wrong Answer)

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

/*
動作確認
*/


class Program
{

	//Main
	static void Main(string[] args)
	{
		//読み込む
		string[] S = Console.ReadLine().Split(' ');
		int N = int.Parse(S[0]);
		int K = int.Parse(S[1]);

		long[] An = Console.ReadLine().Split(' ').Select(i => long.Parse(i)).ToArray();

		long[][] dataArr = new long[N][];
		for(int i=0; i<N; i++){
			dataArr[i] = new long[2];
			if(An[i] >= 0){
				dataArr[i][0] = An[i];
				dataArr[i][1] = 1;
			}else{
				dataArr[i][0] = -1*An[i];
				dataArr[i][1] = 0;
			}
		}

		Array.Sort(dataArr,StructuralComparisons.StructuralComparer);
		Array.Reverse(dataArr);

		long ans = 1;
		long mod = 1000000007;

		/*
		for(int i=0; i<N; i++){
			Console.WriteLine("abs:{0},plus:{1}", dataArr[i][0], dataArr[i][1]);
		}
		*/

		//マイナスの数を累積
		int minusCnt = 0;
		for(int i=0; i<K; i++){
			if(dataArr[i][1] == 0){
				minusCnt ++;
			}
		}

		//偶数の場合、順にかけていけば良いだけ
		if(minusCnt % 2 == 0){
			//Console.WriteLine("OK");
			for(int i=0; i<K; i++){
				ans *= (dataArr[i][0]%mod);
				ans %= mod;
				//Console.WriteLine("data:{0},:ans{1}",dataArr[i][0],ans);
			}
		}

		//奇数の場合
		else{
			//まず、最も絶対値の小さいマイナスを探す（必ず存在）
			int left = K-1;
			for(int i=K-1; i>=0; i--){
				if(dataArr[i][1] == 0){
					left = i;
					break;
				}
			}

			//次に、最も絶対値の大きい次のプラスを探す
			int right = -1;
			for(int i=K; i<N; i++){
				if(dataArr[i][1] == 1){
					right = i;
					break;
				}
			}

			//rightが見つかっている場合、それを加算
			if(right != -1){
				ans = right%mod;
				ans %= mod;
				//left以外を加算
				for(int i=0; i<K; i++){
					if(i == left){
						continue;
					}
					else{
						ans *= (dataArr[i][0]%mod);
						ans %= mod;
					}
				}
			}
			//rightが見つかっていない場合
			//マイナスにならざるを得ないので、尻から足していく
			else{
				for(int i=0; i<K; i++){
					ans *= (dataArr[N-i-1][0]%mod);
					ans %= mod;
				}

				//マイナスなので計算に注意
				ans = mod - ans;
			}
		}

		Console.WriteLine(ans);
	}
}