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: Runtime Error)

#include <bits/stdc++.h>
using namespace std;

long long A[200005];
vector<long long> sign[2];
vector<long long> stack1[2];

const long long MOD = 1e9+7;

long long modpow(long long a, long long b){
    if(b == 0){
        return 1%MOD;
    }else if(b == 1){
        return a%MOD;
    }else{
        long long temp = modpow(a, b>>1);
        if(b&1){
            return ((temp*temp%MOD)*a)%MOD;
        }else{
            return temp*temp%MOD;
        }
    }
}

int main(){
    int N, K;
    scanf("%d%d", &N, &K);

    bool zeroPossible = false;
    for(int i = 0; i < N; i ++){
        scanf("%lld", &A[i]);
        zeroPossible |= (A[i] == 0);

        if(A[i] > 0){
            sign[0].push_back(A[i]);
        }else if(A[i] < 0){
            sign[1].push_back(-A[i]);
        }
    }

    sort(sign[0].begin(), sign[0].end());
    sort(sign[1].begin(), sign[1].end());

    for(int i: sign[0]){
        stack1[0].push_back(i);
    }
    for(int i: sign[1]){
        stack1[1].push_back(i);
    }
    reverse(stack1[0].begin(), stack1[0].end());
    reverse(stack1[1].begin(), stack1[1].end());

    int indx0 = 0;
    int indx1 = stack1[1].size();
    while(stack1[1].size() > K/2*2 ){
        stack1[1].pop_back();
    }

    long long current_product = 1;
    for(long long i: stack1[1]){
        current_product = current_product*i%MOD;
    }

    while(indx0 + stack1[1].size() < K && indx0 < (int)stack1[0].size()){
        current_product = current_product*stack1[0][indx0]%MOD;
        indx0 ++;
    }
    //printf("%d %d\n", indx0, (int)stack1[1].size());

    if(indx0 + (int)stack1[1].size() < K){
        if(zeroPossible){
            printf("0");
            return 0;
        }
        throw;
    }

    //printf("Here");

    while(indx0 + 2 <= (int)stack1[0].size() && (int)stack1[1].size() >= 2){
        long long x1 = stack1[1].back(); stack1[1].pop_back();
        long long x2 = stack1[1].back(); stack1[1].pop_back();

        long long toDivide = x1*x2;
        long long toMultiply = stack1[0][indx0]*stack1[0][indx0+1];
        //printf("debug: %lld %lld\n", toMultiply, toDivide);
        if(toMultiply >= toDivide){
            current_product = (current_product)*(toMultiply%MOD)%MOD;
            current_product = (current_product)*(modpow(toDivide%MOD, MOD-2))%MOD;
            indx0 += 2;
        }else{
            break;
        }
    }

    printf("%lld", current_product);
    return 0;
}