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>
using namespace std;
#define int long long
using vec_int = vector<int>;
using P = pair<int,int>;
using T = tuple<int,int,int>;
using ll = long long;
#define rep(i, n) for(int i = 0; i < (int)(n); i++)

int charToInt(char c){
    char zero_num = '0';
    return (int)c - (int)zero_num;
}

signed main(){
    int MOD=pow(10,9)+7;
    int N,K;cin>>N>>K;
    vec_int A(N);
    rep(i,N)cin>>A.at(i);

//    vec_int absA(N);
//    rep(i,N)absA.at(i) = abs(A.at(i));
    vector<P> absA(N);
    int zeronum = 0;
    rep(i,N){
        int temp;
        if(A.at(i)==0){
            zeronum++;
            temp=0;
        }else{
            temp=A.at(i)/abs(A.at(i));
        }
        absA.at(i) = make_pair(abs(A.at(i)), temp);
    }


    sort(absA.begin(), absA.end());
    reverse(absA.begin(), absA.end());

    //Aが大きいほうからかけていって、一番大きな数になるものを選ぶ。
    //ただし、積が負になる場合には、2つのうちからましな方を選ぶ
        // 選択された中で一番絶対値の小さな負の数を外し、正の数に置き換える
        // 選択された中で一番絶対値の小さな正の数を外し、負の数に置き換える
    // 上の操作が不可能だった場合には0があるかをチェックにして、あれば0にする
    // それでもだめだったら、絶対値の小さなほうから数をかけていって、マイナスをつけて答えにする

    int answer = 1;
    int last_pos=-1;
    int last_neg=-1;
    int num_pos = 0;
    int num_neg = 0;
    for(int i=0;i<K;i++){
        int abs_val, pmsign; 
        tie(abs_val, pmsign) = absA.at(i);

        //この段階で0が来るようではおしまい
        if(abs_val==0){
            cout<<0<<endl;
            return 0;
        }

        if(pmsign==1){
            num_pos++;
            last_pos = i;
        }else if(pmsign==-1){
            num_neg++;
            last_neg = i;
        }
        answer = (answer*abs_val)%MOD;
    }
    if(num_neg%2==0){
        cout<<answer<<endl;
        return 0;
    }
    // 積が負のとき, Kより先の値で正負の値を探す
    int next_pos = -1;
    int next_neg = -1;
    for(int i= K; i<N;i++){
        int abs_val, pmsign; 
        tie(abs_val, pmsign) = absA.at(i);
        if(pmsign==1){
            if(next_pos==-1){
                next_pos = i;
            }
        }else{
            if(next_neg==-1){
                next_neg = i;
            }
        }
        if(next_pos>=0 && next_neg>=0)break;
    }

    if( (last_pos>=0 && next_neg>=0) && !(last_neg>=0 && next_pos>=0)){
        answer = 1;
        for(int i=0;i<K;i++){
            int abs_val, pmsign; 
            tie(abs_val, pmsign) = absA.at(i);
            if(i==last_pos)continue;
            answer = (answer*abs_val)%MOD;
        }
        int abs_val, pmsign; 
        tie(abs_val, pmsign) = absA.at(next_neg);
        answer = (answer*abs_val)%MOD;
        cout<<answer<<endl;
        return 0;

    }else if( !(last_pos>=0 && next_neg>=0) && (last_neg>=0 && next_pos>=0)){
        answer = 1;
        for(int i=0;i<K;i++){
            int abs_val, pmsign; 
            tie(abs_val, pmsign) = absA.at(i);
            if(i==last_neg)continue;
            answer = (answer*abs_val)%MOD;
        }
        int abs_val, pmsign; 
        tie(abs_val, pmsign) = absA.at(next_pos);
        answer = (answer*abs_val)%MOD;
        cout<<answer<<endl;
        return 0;
    }else if((last_pos>=0 && next_neg>=0) && (last_neg>=0 && next_pos>=0)){
        int last_selected;
        int next_selected;
        int abs1, sign1, abs2,sign2, abs3, sign3, abs4, sign4;
        tie(abs1,sign1) = absA.at(last_pos);
        tie(abs2,sign2) = absA.at(last_neg);
        tie(abs3,sign3) = absA.at(next_pos);
        tie(abs4,sign4) = absA.at(next_neg);
        // next_pos/last_neg > next_neg/last_pos -> next_pos*last_pos > next_neg*last_neg
        // だったら、last_negを落として、next_posを入れる
        if(next_pos*last_pos>next_neg*last_neg){
            last_selected = last_neg;
            next_selected = next_pos;
        }else{
            last_selected = last_pos;
            next_selected = next_neg;
        }

        answer = 1;
        for(int i=0;i<K;i++){
            int abs_val, pmsign; 
            tie(abs_val, pmsign) = absA.at(i);
            if(i==last_selected)continue;
            answer = (answer*abs_val)%MOD;
        }
        int abs_val, pmsign; 
        tie(abs_val, pmsign) = absA.at(next_selected);
        answer = (answer*abs_val)%MOD;
        cout<<answer<<endl;
        return 0;



    }else{
        if(zeronum>0){
            cout<<0<<endl;
            return 0;
        }else{
            int temp = 1;
            rep(i,K){
                int abs_val, pmsign; 
                tie(abs_val, pmsign) = absA.at(N-i-1);
                temp = (temp*abs_val)%MOD;
            }
            cout<<MOD-temp<<endl;
            return 0;
        }

    }






    return 0;
}