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)

// ABC173-E
#include <bits/stdc++.h>
#define endl "\n"
#define rep(i,n) for(int i=0;i<int(n);i++)
#define e_b emplace_back
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> ipair;
typedef pair<ll,ll> lpair;
template <class T>ostream &operator<<(ostream &o,const vector<T>&v) //vectorの中身を見る
{o<<"{";for(int i=0;i<(int)v.size();i++)o<<(i>0?", ":"")<<v[i];o<<"}";return o;}
void map_p(map<int,int>& d){cout<<"map: ";for(auto a : d){cout<<"{"<<a.first<<":"<<a.second<<"}";}cout<<endl;} //mapの中身を見る
void set_p(set<int>& d){cout<<"set: ";for(int a : d){cout<<a<<" ";}cout<<endl;} //setの中身を見る

ll mod=pow(10,9)+7;
ll n,k;
vector<ll> num;
bool comp(ll a,ll b){
    return abs(a)>abs(b);
}
ll neg_pos(ll zan_max_pos){
    ll ans=1;
    int c_f_neg=0;
    rep(i,k){
        if(num[k-1-i]<0 && c_f_neg==0){ //上位K個のうち、下から見て初めての負の数は使わない
            c_f_neg++;
            continue;
        }
        ans*=num[k-1-i];
        ans%=mod;
        if(ans<0){
            ans+=mod;
        }
    }
    ans*=zan_max_pos; //余ってる正の数のうち、abs最大の数使う
    ans%=mod;
    if(ans<0){
        ans+=mod;
    }
    return ans;
}
ll pos_neg(ll zan_max_neg){
    ll ans=1;
    int c_f_pos=0;
    rep(i,k){
        if(num[k-1-i]>0 && c_f_pos==0){ //上位K個のうち、下から見て初めての正の数は使わない
            c_f_pos++;
            continue;
        }
        ans*=num[k-1-i];
        ans%=mod;
        if(ans<0){
            ans+=mod;
        }
        return ans;
    }
    ans*=zan_max_neg; //余ってる負の数のうち、abs最大の数使う
    ans%=mod;
    if(ans<0){
        ans+=mod;
    }
    return ans;
}
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(12);

    cin>>n>>k;
    num.assign(n,0);
    ll neg=0,pos=0;
    rep(i,n){
        cin>>num[i];
        if(num[i]<0) neg++;
        else pos++;
    }
    ll ans=1;
    sort(all(num),comp); //絶対値の大きい順に
    if(n==k){ //全て使うしかない
        rep(i,k){
            ans*=num[i];
            ans%=mod;
            if(ans<0){
                ans+=mod;
            }
        }
    }else if(n==neg){ //負しかない
        if(k%2==0){
            rep(i,k){
                ans*=num[i];
                ans%=mod;
                if(ans<0){
                    ans+=mod;
                }
            }
        }else{ //絶対に負になる
            rep(i,k){
                ans*=num[n-1-(i)];
                ans%=mod;
                if(ans<0){
                    ans+=mod;
                }
            }
        }
    }else{ //正がある
        ll c_neg=0; //使った負の数
        ll c_zero=0;
        ll c_pos=0;
        rep(i,k){
            if(num[i]<0) c_neg++;
            else if(num[i]==0) c_zero++;
            else c_pos++;
            ans*=num[i];
            ans%=mod;
            if(ans<0){
                ans+=mod;
            }
        }
        // 積が0以上ならそれが答え
        if(c_neg%2==1 && c_zero==0){ //積が負の状態 数字が1つ以上余ってる
            ll zan_max_pos=-1;
            ll zan_max_neg=1;
            ll use_min_pos=-1;
            ll use_min_neg=1;
            rep(i,k){
                if(num[i]>0){
                    use_min_pos=num[i];
                }
                if(num[i]<0){
                    use_min_neg=num[i];
                }
            }
            for(int i=n-1;i>=k;i=i-1){
                if(num[i]>=0){ //0も余ってる可能性がある
                    zan_max_pos=num[i];
                }
                if(num[i]<0){
                    zan_max_neg=num[i];
                }   
            }
            if(c_pos==0){ //正を使ってない 余りに正がある
                ans=neg_pos(zan_max_pos);
            }else if(neg-c_neg==0){ //0以上しか余ってない
                ans=neg_pos(zan_max_pos);
            }else if(pos-c_pos==0){ //負しか余ってない
                ans=pos_neg(zan_max_neg);
            }else{
                if(zan_max_pos*use_min_pos<abs(zan_max_neg)*abs(use_min_neg)){ //余りから負、使用から正を交換
                    ans=pos_neg(zan_max_neg);
                }else{
                    ans=neg_pos(zan_max_pos);
                }
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}