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

const MOD: i64 = 1e9 as i64 + 7;
fn main() {
    let (r, w) = (std::io::stdin(), std::io::stdout());
    let mut sc = IO::new(r.lock(), w.lock());
    let n: usize = sc.read();
    let k: usize = sc.read();

    let mut positive: Vec<i64> = vec![];
    let mut negative: Vec<i64> = vec![];
    for _ in 0..n {
        let a: i64 = sc.read();
        if a > 0 {
            positive.push(a);
        }
        if a < 0 {
            negative.push(a);
        }
    }

    let zero_count = n - (positive.len() + negative.len());

    if n - zero_count < k || (positive.is_empty() && zero_count > 0 && k % 2 == 1) {
        println!("0");
        return;
    }

    if negative.len() == n && k % 2 == 1 {
        // must negative
        negative.sort();
        negative.reverse();
        let mut ans = 1;
        for i in 0..k {
            ans *= -negative[i];
            ans %= MOD;
        }
        println!("{}", (MOD - ans) % MOD);
        return;
    }

    let mut log_max = 1.0f64;
    let mut max_neg_count = 0;
    negative.sort();
    positive.sort();
    positive.reverse();

    let mut remain = k;
    while remain >= 2 && negative.len() >= max_neg_count + 2 {
        log_max += (-negative[max_neg_count] as f64).log10();
        log_max += (-negative[max_neg_count + 1] as f64).log10();
        max_neg_count += 2;
        remain -= 2;
    }
    let mut positive_pos = 0;
    if remain == 1 {
        log_max += (positive[0] as f64).log10();
        positive_pos += 1;
    }

    let mut cur_log = log_max;
    let mut cur_neg_count = max_neg_count;
    while cur_neg_count >= 2 && positive_pos + 2 <= positive.len() {
        cur_log -= (-negative[cur_neg_count - 1] as f64).log10();
        cur_log -= (-negative[cur_neg_count - 2] as f64).log10();
        cur_log += (positive[positive_pos] as f64).log10();
        cur_log += (positive[positive_pos + 1] as f64).log10();
        cur_neg_count -= 2;
        positive_pos += 2;
        if cur_log > log_max {
            log_max = cur_log;
            max_neg_count = cur_neg_count;
        }
    }

    let mut ans = 1;
    for i in 0..max_neg_count {
        ans *= -negative[i];
        ans %= MOD;
    }
    for i in 0..(k - max_neg_count) {
        ans *= positive[i];
        ans %= MOD;
    }
    println!("{}", ans);
}

pub struct IO<R, W: std::io::Write>(R, std::io::BufWriter<W>);

impl<R: std::io::Read, W: std::io::Write> IO<R, W> {
    pub fn new(r: R, w: W) -> Self {
        Self(r, std::io::BufWriter::new(w))
    }
    pub fn write<S: ToString>(&mut self, s: S) {
        use std::io::Write;
        self.1.write(s.to_string().as_bytes()).unwrap();
    }
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n' || b == b'\r' || b == b'\t')
            .take_while(|&b| b != b' ' && b != b'\n' && b != b'\r' && b != b'\t')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}