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: Accepted)

#include<iostream>
#include<iomanip>
#include<cassert>
#include<math.h>
#include<complex>
#include<algorithm>
#include<utility>
#include<queue>
#include<string.h>
#include<string>
#include<set>
#include<map>
#include<unordered_map>
#include<functional>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
const ll INF=2e18;
const ll MOD=1e9+7;

ll extgcd(ll a, ll b, ll& x, ll& y) {//ax+by=1
  if (b == 0) {
    x = 1, y = 0; return a;
  }
  ll q = a/b, g = extgcd(b, a - q*b, x, y);
  ll z = x - q * y;
  x = y;
  y = z;
  return g;
}

ll invmod (ll a, ll m) { // a^-1 mod m
  ll x, y;
  extgcd(a, m, x, y);
  x %= m;
  if (x < 0) x += m;
  return x;
}

ll N,K;
P A[200010];
int state=-1;
int main(){
    cin>>N>>K;
    for(ll i=0;i<N;i++){
        ll a;
        cin>>a;
        if(a<0) A[i]=P(-a,-1);
        else if(a>0){
            A[i]=P(a,1);
            state=1;
        }else{
            A[i]=P(a,0);
            if(state==-1)state=0;
        }
    }
    ll ans=1;
    if(state==-1){
        if(K%2==1){
            sort(A,A+N);
            for(ll i=0;i<K;i++){
                ans=(ans*A[i].first)%MOD;
            }
            cout<<(MOD-ans)<<endl;
        }else{
            sort(A,A+N,greater<P>());
            for(ll i=0;i<K;i++){
                ans=(ans*A[i].first)%MOD;
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    if(state==0){
        if(K%2==1){
            cout<<0<<endl;
        }else{
            sort(A,A+N,greater<P>());
            for(ll i=0;i<K;i++){
                ans=(ans*A[i].first)%MOD;
            }
            cout<<ans<<endl;
        }
        return 0;
    }

    sort(A,A+N,greater<P>());
    ll minusCnt=0;
    ll plusMin=INF,minusMin=INF;
    for(ll i=0;i<K;i++){
        if(A[i].second==-1){
            minusCnt++;
            minusMin=min(minusMin,A[i].first);
        }else{
            plusMin=min(plusMin,A[i].first);
        }
        ans=(ans*A[i].first)%MOD;
    }
    if(minusCnt%2==0){
        cout<<ans<<endl;
        return 0;
    }
    if(K==N){
        if(ans==0){
            cout<<0<<endl;
        }else{
            cout<<(MOD-ans)<<endl;
        }
        return 0;
    }
    ll plusMax=-1;
    ll minusMax=-1;
    for(ll i=K;i<N;i++){
        if(A[i].second==1){
            plusMax=max(plusMax,A[i].first);
        }else if(A[i].second==-1){
            minusMax=max(minusMax,A[i].first);
        }
    }
    if(plusMax==-1 && minusMax==-1){
        cout<<0<<endl;
        return 0;
    }
    if(plusMin==INF){
        cout<<ans*invmod(minusMin,MOD)%MOD*plusMax%MOD<<endl;
        return 0;
    }

    if(plusMax*plusMin < minusMax*minusMin){
        cout<<ans*invmod(plusMin,MOD)%MOD*minusMax%MOD<<endl;
    }else{
        cout<<ans*invmod(minusMin,MOD)%MOD*plusMax%MOD<<endl;
    }
    return 0;
}