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 (GCC 9.2.1) (judge verdict: Wrong Answer)

#include <stdio.h>

void swap(long long int *a, long long int *b)
{
	long long int tmp;
	tmp = *a;
	*a = *b;
	*b = tmp;
}

int abs_int(long long int a)
{
	if (a >= 0) return a;
	return -a;
}

void merge_sort (long long int array[], int left, int right)
{
	int i, j, k, mid;
	int work[300000];

	if (left < right)
	{
		mid = (left + right) / 2;
		merge_sort(array, left, mid);
		merge_sort(array, mid+1, right);
		for (i = mid; i >= left; i--)
		{
			work[i] = array[i];
		}
		for (j = mid+1; j <= right; j++)
		{
			work[right-(j-(mid+1))] = array[j];
		}
		i = left; j = right;
		for (k = left; k <= right; k++)
		{
			if (abs_int(work[i]) > abs_int(work[j]))
			{
				array[k] = work[i++];
			}
			else
			{
				array[k] = work[j--];
			}
		}
	}
}

int main(void)
{
	int n, k;
	long long int a[300000];
	long long int ans = 1;
	long long int ans2, ans3;
	int i, j, l, f, f2, f3;
	double s2, s3;

	scanf("%d%d", &n, &k);

	f = 1;
	for (i = 0; i < n; i++)
	{
		scanf("%lld", &a[i]);
		if (a[i] > 0) f = 0;
	}

	merge_sort(a, 0, n - 1);

	if (n == k)
	{
		for (i = 0; i < k; i++)
		{
			ans *= a[i];
			ans %= 1000000007;
		}
	}
	else if (f == 1 && k % 2 == 1)
	{
		for (i = 0; i < k; i++)
		{
			ans *= a[n - 1 - i];
			ans %= 1000000007;
		}
	}
	else
	{
		for (i = 0; i < k; i++)
		{
			ans *= a[i];
			ans %= 1000000007;
		}
		if (ans < 0)
		{
			f2 = f3 = 0;
			s2 = s3 = -1;
			for (i = k - 1; i >= 0; i--)
			{
				if (a[i] < 0 && f2 == 0)
				{
					f2 = 1;
					for (j = k; j < n; j++)
					{
						if (a[j] > 0)
						{
							ans2 = 1;
							for (l = 0; l < k; l++)
							{
								if (l == i) continue;
								ans2 *= a[l];
								ans2 %= 1000000007;
							}
							ans2 *= a[j];
							ans2 %= 1000000007;
							s2 = -(double)a[j] / a[i];
							break;
						}
					}
				}
				else if(a[i] > 0 && f3 == 0)
				{
					f3 = 1;
					for (j = k; j < n; j++)
					{
						if (a[j] < 0)
						{
							ans3 = 1;
							for (l = 0; l < k; l++)
							{
								if (l == i) continue;
								ans3 *= a[l];
								ans3 %= 1000000007;
							}
							ans3 *= a[j];
							ans3 %= 1000000007;
							s3 = -(double)a[j] / a[i];
							break;
						}
					}
				}
			}
			if (s2 > s3) ans = ans2;
			else ans = ans3;
		}
	}

	ans %= 1000000007;
	if (ans < 0) ans += 1000000007;

	printf("%lld\n", ans);

	return 0;
}