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::cmp::Reverse;
use std::collections::BinaryHeap;
use std::collections::HashMap;

fn read_line() -> String {
    let mut buffer = String::new();
    std::io::stdin().read_line(&mut buffer).expect("No Line");
    buffer
}
fn read_lines<R, T: Fn(&str)->R> (count: usize, transformer: T) -> Vec<R> {
    let mut buffer = String::new();
    let mut vec = Vec::with_capacity(count);
    for _ in 0 .. count {
        std::io::stdin().read_line(&mut buffer).expect("No Line");
        vec.push(transformer(buffer.trim()));
        buffer.clear();
    }
    vec
}
fn read_value<T: std::str::FromStr>() -> T {
    read_line().trim().parse().ok().unwrap()
}
fn read_values<T: std::str::FromStr>() -> Vec<T> {
    read_line().trim().split(' ').map(|x| x.parse().ok().expect("Can't Parse")).collect::<Vec<T>>()
}
fn read_tabulate<T: std::str::FromStr>(count: usize) -> Vec<T> {
    let mut buffer = String::new();
    let mut vec = Vec::with_capacity(count);
    for _ in 0 .. count {
        std::io::stdin().read_line(&mut buffer).expect("No Line");
        vec.push(buffer.trim().parse().ok().expect("Can't Parse"));
        buffer.clear();
    }
    vec
}
macro_rules! assign {
    () => {};
    ($($token:tt)*) => {
        let mut iter = read_values::<String>().into_iter();
        assign_iter!(iter, $($token)*);
    };
}
macro_rules! assign_iter {
    ($iter:expr) =>{};
    ($iter:expr,) =>{};
    ($iter:expr, $id:ident:$t:tt $($tail:tt)*) => {
        let $id: $t = $iter.next().unwrap().parse().ok().expect("Can't Parse");
        assign_iter!($iter, $($tail)*);
    };
    ($iter:expr, mut $id:ident:$t:tt $($tail:tt)*) => {
        let mut $id: $t = $iter.next().unwrap().parse().ok().expect("Can't Parse");
        assign_iter!($iter, $($tail)*)
    };
}
macro_rules! freeze {
    ($($id:ident), *) => {
        $(let $id = $id;)*
    };
}
fn main() {
    assign! {
        n: usize
        k: usize
    }
    let modulo = 1000000007i64;
    let values = read_values::<i64>();
    let mut plus = Vec::new();
    let mut minus = Vec::new();
    for &v in &values {
        if v > 0 {
            plus.push(v);
        }else if v < 0 {
            minus.push(-v);
        }
    }
    let plus_count = plus.len();
    let miuns_count = minus.len();
    if plus_count + ((miuns_count >> 1) << 1) >= k && ((k & 1) != 1 || plus_count > 0) {
        plus.sort_by_key(|&v| Reverse(v));
        minus.sort_by_key(|&v| Reverse(v));
        plus.insert(0, 1i64);
        minus.insert(0, 1i64);
        let mut plus_log = Vec::with_capacity(plus.len());
        let mut minus_log = Vec::with_capacity(minus.len());
        for &p in &plus {
            plus_log.push((p as f64).log2());
        }
        for i in 1 .. plus.len() {
            plus[i] = plus[i] * plus[i - 1] % modulo;
            plus_log[i] += plus_log[i - 1];
        }
        for &m in &minus {
            minus_log.push((m as f64).log2());
        }
        for i in 1 .. minus.len() {
            minus[i] = minus[i] * minus[i - 1] % modulo;
            minus_log[i] += minus_log[i - 1];
        }
        let mut max_log = 0f64;
        let mut max_mod = 1i64;
        for i in (0 .. minus_log.len()).step_by(2) {
            if i > k {break;}
            if k - i >= plus_log.len() {continue;}
            let log = minus_log[i] + plus_log[k - i];
            if max_log < log {
                max_log = log;
                max_mod = minus[i] * plus[k - i] % modulo;
            }
        }
        println!("{}", max_mod);
    }else {
        let mut values = values;
        values.sort_by_key(|&v| v.abs());
        let mut max_mod = 1i64;
        for i in 0 .. k {
            max_mod = max_mod * values[i].abs() % modulo;
        }
        println!("{}", (modulo - max_mod) % modulo);
    }
}