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 Rust (1.42.0) (judge verdict: Accepted)

macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        let mut next = || { iter.next().unwrap() };
        input_inner!{next, $($r)*}
    };
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

fn main() {
    input! {
        n: usize,
        kk: usize,
        av: [i64; n],
    }
    let _mod = 1000000007;
    let mut ans = 1;
    if kk == n {
        for a in &av {
            ans *= a;
            ans %= _mod;
        }
        if ans < 0 {
            ans += _mod;
        }
    } else {
        let mut bv = vec![];
        let mut cv = vec![];
        for a in &av {
            if *a < 0 { bv.push(a); }
            else    { cv.push(a); }
        }
        bv.sort();
        cv.sort();   
        cv.reverse();
        let mut b = 0;
        let mut c = 0;
        let mut k = kk;
        loop {
            if k > 1 {
                let mut bb = 0;
                if b+1 < bv.len()  { bb = bv[b] * bv[b+1]; }
                let mut cc = 0;
                if c+1 < cv.len()  { cc = cv[c] * cv[c+1]; }
                if bb > cc {
                    ans *= bb%_mod;
                    k -= 2;
                    b += 2;
                } else {
                    ans *= cv[c]%_mod;
                    k -= 1;
                    c += 1;
                }
                ans %= _mod;
                if k == 0 { break; }
            } else if k == 1 {
                if c < cv.len() {
                    ans *= cv[c];
                    ans %= _mod;
                } else if b < bv.len() {
                    ans = 1;
                    for i in 0..kk {
                        ans *= bv[bv.len()-i-1];
                        ans %= _mod;
                    }
                    ans += _mod;
                }
                if ans < 0 { ans += _mod; }
                break;
            }
        }
    }
    println!("{}", ans);
}