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)

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 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![];

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

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

    if neg.len() == vec.len() {
        if k % 2 == 1 {
            neg.reverse();
        }
        return product(&neg[0..k].to_vec(), MOD);
    }

    let mut i = std::cmp::min(k, pos.len());
    let mut j = k - i;

    if j % 2 == 1 && j < neg.len() && i > 0 {
        i -= 1;
        j += 1;
    }

    while i > 1 && j + 1 < neg.len() {
        let p = pos[i - 1] * pos[i - 2];
        let n = neg[j] * neg[j + 1];
        if p >= n {
            break;
        }

        i -= 2;
        j += 2;
    }

    let mut res = pos[0..i].to_vec();
    res.append(&mut neg[0..j].to_vec());
    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);
}