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<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
using namespace std;
typedef long long ll;
const int maxn = 1e6+5;
const double esp = 1e-7;
const int ff = 0x3f3f3f3f;
map<int,int>::iterator it;
ll Produc_Mod(ll a, ll b)
{
	ll sum = 0;
	while (b)
	{
		if (b & 1) sum = (sum + a) % mod;
		a = (a + a) % mod;
		b >>= 1;
	}
	return sum%mod;
}

struct node
{
	ll x;
	int f;
}a[maxn];

ll n,k;

bool cmp(node x,node y)
{
	return x.x> y.x;
}

ll solve(int o)
{
	ll ans = 1;
	int cnt = 0;
	if(o == 0)//从前往后乘 
	{
		for(int i = 1;i<= k;i++)
		{
			ans = (Produc_Mod(ans,a[i].x)%mod+mod)%mod;
			if(a[i].f == 1)
				cnt++;
		}
	}
	else//从后往前乘 
	{
		for(int i = n;i> n-k;i--)
		{
			ans = (Produc_Mod(ans,a[i].x)%mod+mod)%mod;
			if(a[i].f == 1)
				cnt++;
		}
	}
	
	if(cnt&1)
		return ans*(-1);
	return ans;
}

int main()
{
	cin>>n>>k;
	
	int flag = 0;
	int cnt = 0;
	for(int i = 1;i<= n;i++)
	{
		scanf("%lld",&a[i].x);
		if(a[i].x< 0)
		{
			a[i].f = 1;
			a[i].x = -a[i].x;
			cnt++;
		}
		else if(a[i].x> 0)
			a[i].f = 0;
		else
		{
			i--;n--;//我们不记录0，0只做迫不得已的选择 
			flag = 1;
		}
	}
	
	sort(a+1,a+n+1,cmp);
	
	ll ans = 0;
	
	if(n< k)//如果必须选0 
		ans = 0;
	else if(cnt == n)//如果都为负数 
	{
		if(k&1)
			ans = solve(1);
		else
			ans = solve(0);
	}
	else if(cnt == 0)//如果都为正数 
		ans = solve(0);
	else
	{
		int tmp = 0;
		for(int i = 1;i<= k;i++)
			if(a[i].f == 1)
				tmp++;
			
		if(tmp%2 == 0)//如果前k大的数有偶数个负数 
			ans = solve(0);
		else
		{
			ans = -1;//将其设置为负数 
			//尝试将前k个里面一个绝对值最小负数和后面最大正数交换 
			int p = -1,q = -1;
			for(int i = k+1;i<= n;i++)
				if(a[i].f == 0)
				{
					q = i;
					break;
				}
			for(int i = k;i>= 1;i--)
				if(a[i].f == 1)
				{
					p = i;
					break;
				}
			
			if(p!= -1&&q!= -1)
			{
				swap(a[p],a[q]);
				ans = solve(0);
				swap(a[p],a[q]);
			}
			
			//尝试将前k个里面一个最小正数和后面绝对值最大正数交换
			p = -1,q = -1;
			for(int i = k+1;i<= n;i++)
				if(a[i].f == 1)
				{
					q = i;
					break;
				}
			for(int i = k;i>= 1;i--)
				if(a[i].f == 0)
				{
					p = i;
					break;
				}
			
			if(p!= -1&&q!= -1)
			{
				swap(a[p],a[q]);
				ans = max(ans,solve(0));
				swap(a[p],a[q]);
			}
			
			//假如结果仍然小于0，我们只能尝试从最后往前乘了 
			if(ans< 0)
				ans = solve(1); 
		}
	}
	
	if(ans< 0)
		if(flag)//这时候0派上用场了 
		{
			cout<<0<<endl;
			return 0;
		}
	cout<<(ans%mod+mod)%mod<<endl;
	
	return 0;
}