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)

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);
        }
    }

    positive.sort();
    positive.reverse();
    negative.sort();

    let mut p_sum = vec![0.0; positive.len() + 1];
    for i in 0..positive.len() {
        p_sum[i + 1] = p_sum[i] + (positive[i] as f64).log10();
    }
    let mut n_sum = vec![0.0; negative.len() + 1];
    for i in 0..negative.len() {
        n_sum[i + 1] = n_sum[i] + (-negative[i] as f64).log10();
    }

    let mut is_positive = false;
    let mut max_log = 0.0;
    let mut max_positive_count = 0;
    for positive_count in 0..=positive.len() {
        if positive_count > k {
            break;
        }
        let negative_count = k - positive_count;
        if negative_count % 2 == 1 {
            continue;
        }
        if negative_count > negative.len() {
            continue;
        }

        is_positive = true;
        let log = p_sum[positive_count] + n_sum[negative_count];
        if max_log < log {
            max_log = log;
            max_positive_count = positive_count;
        }
    }

    if !is_positive {
        let zero = n - positive.len() - negative.len();
        let mut v = vec![];
        for positive in positive.into_iter() {
            v.push(positive);
        }
        for negative in negative.into_iter() {
            v.push(-negative);
        }
        for _ in 0..zero {
            v.push(0);
        }
        v.sort();

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

        return;
    }

    let mut ans = 1;
    let negative_count = k - max_positive_count;
    for i in 0..negative_count {
        ans *= -negative[i];
        ans %= MOD;
    }
    for i in 0..max_positive_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()
    }
}