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)

use std::fmt::Debug;
use std::str::FromStr;

pub struct TokenReader {
    reader: std::io::Stdin,
    tokens: Vec<String>,
    index: usize,
}

impl TokenReader {
    pub fn new() -> Self {
        Self {
            reader: std::io::stdin(),
            tokens: Vec::new(),
            index: 0,
        }
    }

    pub fn next<T>(&mut self) -> T
    where
        T: FromStr,
        T::Err: Debug,
    {
        if self.index >= self.tokens.len() {
            self.load_next_line();
        }
        self.index += 1;
        self.tokens[self.index - 1].parse().unwrap()
    }

    pub fn vector<T>(&mut self) -> Vec<T>
    where
        T: FromStr,
        T::Err: Debug,
    {
        if self.index >= self.tokens.len() {
            self.load_next_line();
        }
        self.index = self.tokens.len();
        self.tokens.iter().map(|tok| tok.parse().unwrap()).collect()
    }

    pub fn load_next_line(&mut self) {
        let mut line = String::new();
        self.reader.read_line(&mut line).unwrap();

        self.tokens = line
            .split_whitespace()
            .map(String::from)
            .collect();
        self.index = 0;
    }
}

fn euclid(a: i64, b: i64) -> (i64, i64) {
    if b == 0 {
        return (1, 0);
    }

    let p = euclid(b, a % b);
    (p.1, p.0 - a / b * p.1)
}

fn inv_mod(num: i64, the_mod: i64) -> i64 {
    let mut inv = euclid(num, the_mod).0;
    while inv < 0 {
        inv += the_mod;
    }
    inv
}

fn product(nums: &Vec<i64>, the_mod: i64) -> i64 {
    let mut prod = 1;
    for &num in nums.iter() {
        prod *= num;
        while prod < 0 {
            prod += the_mod;
        }
        while prod > the_mod {
            prod -= the_mod;
        }
    }
    prod
}

fn solve(vec: &mut Vec<i64>, k: usize) -> i64 {
    const MOD: i64 = 1e9 as i64 + 7;
    if k == vec.len() {
        return product(&vec, MOD);
    }

    let mut pos = vec![];
    let mut neg = vec![];
    let mut zero = 0;

    for &num in vec.iter() {
        if num > 0 {
            pos.push(num);
        } else if num < 0 {
            neg.push(num);
        } else {
            zero += 1;
        }
    }

    pos.sort();
    pos.reverse();
    neg.sort();

    if pos.is_empty() {
        if k % 2 == 1 {
            neg.reverse();
            return if zero > 0 { 0 } else { product(&neg[0..k].to_vec(), MOD) };
        }
        if neg.len() < k {
            return 0;
        }
        return product(&neg[0..k].to_vec(), MOD);
    }

    let mut res = vec![];
    let mut i = 0;
    let mut j = 0;

    while i + 1 < pos.len() && j + 1 < neg.len() && res.len() + 1 < k {
        if pos[i] * pos[i + 1] > neg[i] * neg[i + 1] {
            res.push(pos[i]);
            res.push(pos[i + 1]);
            i += 2;
        } else {
            res.push(neg[i]);
            res.push(neg[i + 1]);
            j += 2;
        }
    }

    if res.len() + 1 == k {
        if i < pos.len() {
            res.push(pos[i]);
        } else if zero > 0 {
            return 0;
        }
    } else if i < pos.len() {
        while j + 1 < neg.len() && neg[j] * neg[j + 1] > pos[i] {
            if res.len() + 1 >= k {
                break;
            }
            res.push(neg[j]);
            res.push(neg[j + 1]);
            j += 2;
        }
        if i < pos.len() && res.len() < k {
            res.push(pos[i]);
        }
    }
    product(&res, MOD)
}

fn main() {
    let mut reader = TokenReader::new();
    let _ = reader.next::<usize>();
    let k = reader.next::<usize>();
    let mut vec = reader.vector::<i64>();

    let res = solve(&mut vec, k);
    println!("{}", res);
}