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)

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<n;i++)
#define cinf(n,x) for(int i=0;i<(n);i++)cin>>x[i];
#define ft first
#define sc second
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define all(v) (v).begin(),(v).end()
#define LB(a,x) lb(all(a),x)-a.begin()
#define UB(a,x) ub(all(a),x)-a.begin()
#define mod 1000000007
#define FS fixed<<setprecision(15)
using namespace std;
typedef long long ll;
const double pi=3.141592653589793;
template<class T> using V=vector<T>;
using Graph = vector<vector<int>>;
using P=pair<ll,ll>;
typedef unsigned long long ull;
typedef long double ldouble;
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }

const ll INF=1e18;

int main(){
    cin.tie(0);ios::sync_with_stdio(false);
    ll n,k;
    cin>>n>>k;
    ll p=0,m=0,z=0;
    V<ll> a(n);
    priority_queue<ll,V<ll>,greater<ll>> qm,qq,Q,QQ;
    priority_queue<ll> qp;
    rep(i,n){
        cin>>a[i];
        qq.push(abs(a[i]));
        if(a[i]>0){
            p++;
            qp.push(a[i]);
        }
        else if(a[i]==0)z++;
        else{
            m++;
            qm.push(a[i]);
        }
    }
    if(p+m<k)cout<<0<<endl;
    else{
        sort(all(a),greater<ll>());
        V<ll> b(k);
        rep(i,k)b[i]=a[i];
        bool ok=0;
        ll ans=1;
        for(ll i=0;i<=k;i+=2){
            if(i>m) break;
            if(k-i<=p){
                if(!ok){
                    rep(j,i){
                        QQ.push(abs(qm.top()));
                        qm.pop();
                    }
                    rep(j,k-i){
                        Q.push(abs(qp.top()));
                        qp.pop();
                    }
                }else{
                    ll s=qm.top();
                    qm.pop();
                    ll t=qm.top();
                    qm.pop();
                    ll A=Q.top();
                    Q.pop();
                    ll B=Q.top();
                    Q.pop();
                    if(abs(s*t)<=A*B){
                        Q.push(abs(A));
                        Q.push(abs(B));
                    }else{
                        QQ.push((s));
                        QQ.push((t));
                    }
                    
                }
                
                //if(!ok)
                ok=1;
            }
        }
        if(!ok){
            rep(i,k){
                ans=(ans*abs(qq.top()))%mod;
                qq.pop();
            }
            if(ans>0)ans=mod-ans;
            else if(ans<0)ans=ans+mod;
        }else{
            while(!Q.empty()){
                ll now=Q.top();
                Q.pop();
                ans=(ans*now)%mod;
            }
            while(!QQ.empty()){
                ll now=abs(QQ.top());
                QQ.pop();
                ans=(ans*now)%mod;
            }
        }
        while(ans<0)ans+=mod;
        cout<<ans<<endl;
    }
}
//ペナルティ出しても焦らない　ACできると信じろ！！！
//どうしてもわからないときはサンプルで実験　何か見えてくるかも
//頭で考えてダメなら紙におこせ！！
/*
V,P(大文字)使用不可
乗算などの際にオーバーフローに注意せよ！
(適切にmodをとれ　にぶたんで途中で切り上げろ)
制約をよく読め！
{
    ・全探索できるなら全探索しろ
    ・異常な制約ならそこに注目
}
stringの計算量(扱い)注意
コーナー注意！(特に数値が小さいものについては要検証)
N行出力のときは'¥n'
グリッド上では行先が範囲内におさまるかif文で確認(RE注意)
if文ではちゃんと比較演算子==を使え('='でもエラー出ない)
配列(vector)の大きさが0か1以上かで場合分けせよ(RE注意)
(vector<int> a(m)でm==0というものはできない)
modはなるべく最後に取れ！
doubleを扱うときには(abs)ではなく'fabs'!!!
*/