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>
#define endl "\n"
using namespace std;
#define ll long long
#define ld long double
#define ui unsigned int
#define ull unsigned ll
#define foi(n) for(ll i=0;i<n;i++)
#define foj(n) for(ll j=0;j<n;j++)
#define fok(n) for(ll k=0;k<n;k++)
#pragma GCC optimize("O3", "unroll-loops")
#define fixed(); cout << fixed << setprecision(20);
#define fast(); ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);

/*****************************************************************************/


#define graph          vector<vector<int>>
#define V              vector
typedef pair<int, int> pii;
typedef pair<ll, ll>   pll;
typedef V<int>         vi;
typedef V<ll>          vll;
typedef V<string>      vs;
typedef V<double>      vd;
typedef V<pii>         vpii;             
typedef V<pll>         vpll;             
typedef pair<int,pii>  piii;             
typedef priority_queue<pii, vector<pii>, greater<pii> > pqq;   

/*****************************************************************************/

#define mp                   make_pair
#define eb                   emplace_back
#define pb                   push_back
#define pf                   push_front
#define popb                 pop_back
#define popf                 pop_front
#define hashmap              unordered_map
#define hashset              unordered_set
#define lb                   lower_bound
#define ub                   upper_bound
#define all(a)               (a).begin(), (a).end()
#define rall(a)              (a).rbegin(), (a).rend()
#define ff                   first
#define ss                   second
#define lbpos(v,x)           (int)(lower_bound(all(v),x)-v.begin())//=v.size()==>No LB 
#define ubpos(v,x)           (int)(upper_bound(all(v),x)-v.begin())//=v.size()==>No UB

/*****************************************************************************/

//for declaring most used global variables and constants
ll mod=1e9+7;

//For Calculating nCr
template<typename T>
T nCr(T n, T r) {
    if(r > n - r) r = n - r; // because C(n, r) == C(n, n - r)
    int  ans = 1,i;
    for(i = 1; i <= r; i++) {
        ans *= n - r + i;
        ans /= i;
    } return ans;
}

//power optimized
template<typename T,typename T2>
T2 power(T x, T y) 
{ 
    if (y == 0)  return 1; 
    T2 res=power(x,y/2);
    if (y % 2)  return res*res*x;
    return res*res; 
}

//return number of set bits in a given number
template<typename T>
ll countSetBits(T n) 
{ 
    return __builtin_popcount (n);
}

//return true if number is prime
template<typename T>
bool isPrime(T n) 
{ 
    // Corner cases 
    if (n <= 1)  return false; 
    if (n <= 3)  return true; 
    if (n % 2 == 0 || n % 3 == 0)  return false; 
    for (ll i = 5; i * i <= n; i = i + 6) 
        if (n % i == 0 || n % (i + 2) == 0) 
            return false; 
   return true; 
} 

//return true if string is palindrome
bool ispalindrome(string s)
{
    ll len=s.length();
    foi(len){
        if(s[i]!=s[len-i-1])
        return false;
    }
    return true;
}

#define int long long
int maxProductSubarrayOfSizeK(int A[], int n, int k) 
{ 
    // sorting given input array 
    sort(A, A + n); 

    // variable to store final product of all element 
    // of sub-sequence of size k 
    int product = 1; 

    // CASE I 
    // If max element is 0 and 
    // k is odd then max product will be 0 
    if (A[n - 1] == 0 && (k & 1)) 
        return 0; 

    // CASE II 
    // If all elements are negative and 
    // k is odd then max product will be 
    // product of rightmost-subarray of size k 
    if (A[n - 1] <= 0 && (k & 1)) { 
        for (int i = n - 1; i >= n - k; i--) 
            {product *= A[i];  product%=mod;}
        return product; 
    } 

    // else 
    // i is current left pointer index 
    int i = 0; 

    // j is current right pointer index 
    int j = n - 1; 

    // CASE III 
    // if k is odd and rightmost element in 
    // sorted array is positive then it 
    // must come in subsequence 
    // Multiplying A[j] with product and 
    // correspondingly changing j 
    if (k & 1) { 
        product *= A[j]; 
        product%=mod;
        j--; 
        k--; 
    } 

    // CASE IV 
    // Now k is even 
    // Now we deal with pairs 
    // Each time a pair is multiplied to product 
    // ie.. two elements are added to subsequence each time 
    // Effectively k becomes half 
    // Hence, k >>= 1 means k /= 2 
    k >>= 1; 

    // Now finding k corresponding pairs 
    // to get maximum possible value of product 
    for (int itr = 0; itr < k; itr++) { 

        // product from left pointers 
        int left_product = A[i] * A[i + 1]; 

        // product from right pointers 
        int right_product = A[j] * A[j - 1]; 

        // Taking the max product from two choices 
        // Correspondingly changing the pointer's position 
        if (left_product > right_product) { 
            product *= left_product; 
            product%=mod;
            i += 2; 
        } 
        else { 
            product *= right_product; 
            product%=mod;
            j -= 2; 
        } 
    } 

    // Finally return product 
    return product; 
} 



//for string with space use std::getline(cin,string_name);
//*****************UVAISH ZAFRI(Rush_For_AC)**********************

int32_t main() {
    fast();fixed();
    #ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
   
    ll n,k;
    cin>>n>>k;
    ll a[n];
    foi(n)
    cin>>a[i];
    ll ans=maxProductSubarrayOfSizeK(a,n,k);
    if(ans>0) cout<<ans<<endl;
    else{
        cout<<mod-(abs(ans))%mod<<endl;
    }


                
    return 0;
}