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: Wrong Answer)

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;
    let mut has_zero = false;
    let mut has_pos = false;

    for &num in vec.iter() {
        if num == 0 {
            has_zero = true;
        } else if num > 0 {
            has_pos = true;
        }
    }

    if k % 2 == 1 && !has_pos {
        if has_zero {
            return 0;
        }

        vec.sort();
        vec.reverse();
        return product(&vec[0..k].to_vec(), MOD);
    }

    vec.sort_by(|&a, &b| b.abs().cmp(&a.abs()));

    let mut used = vec![false; vec.len()];
    let mut left = k;
    let mut prev_neg: Option<usize> = None;
    let mut prev_pos: Option<usize> = None;

    for i in 0..vec.len() {
        if left == 0 {
            break;
        }
        if vec[i] == 0 {
            used[i] = true;
            left = 0;
            break;
        }

        if vec[i] > 0 {
            used[i] = true;
            left -= 1;
            prev_pos = Some(i);
            continue;
        }

        if prev_neg.is_none() {
            prev_neg = Some(i);
            continue;
        }

        let j = prev_neg.unwrap();
        if left >= 2 {
            used[j] = true;
            used[i] = true;
            left -= 2;
            prev_neg = None;
            continue;
        }

        if prev_pos.is_none() {
            continue;
        }

        let z = prev_pos.unwrap();
        if vec[j].abs() >= vec[z].abs() {
            used[z] = false;
            left -= 1;
            used[j] = true;
            used[i] = true;
            left += 2;
            prev_neg = None;
            prev_pos = None;
            continue;
        }
    }

    for i in 0..vec.len() {
        if !used[i] && vec[i] > 0 && left > 0 {
            used[i] = true;
            left -= 1;
        }
    }
    for i in (0..vec.len()).rev() {
        if !used[i] && left > 0 {
            used[i] = true;
            left -= 1;
        }
    }

    let nums = (0..vec.len()).filter(|&i| used[i]).map(|i| vec[i]).collect();
    product(&nums, 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);
}