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 core::cmp::max;
use std::cmp::Reverse;

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 pow_mod(base: i64, exp: usize, modulo: i64) -> i64 {
    match exp {
        0usize => 1i64,
        1usize => base % modulo,
        _ => pow_mod(base * base % modulo, exp >> 1, modulo) * pow_mod(base, exp & 1, modulo) % modulo
    }
}
fn main() {
    assign! {
        n: usize
        k: usize
    }
    let modulo = 1000000007i64;
    let mut values = read_values::<i64>();
    values.sort_by_cached_key(|&v| Reverse(v.abs()));
    let mut last_positive: Option<usize> = None;
    let mut last_negative: Option<usize> = None;
    let mut result = 1i64;
    for i in 0 .. k {
        result = result * values[i] % modulo;
        if values[i] > 0 {
            last_positive = Some(i);
        }else if values[i] < 0 {
            last_negative = Some(i);
        }
    }
    if result >= 0 {
        println!("{}", result);
    }else if values.iter().any(|&v| v > 0) {
        let mut pair:Option<(i64, i64)> = None;
        if let Some(pos) = last_positive {
            let remove = values[pos];
            if let Some(neg) = (k .. n).find(|&i| { values[i] < 0 }) {
                let add = values[neg];
                if let Some((max_add, max_remove)) = pair {
                    if max_remove.abs() * add.abs() > max_add.abs() * remove.abs() {
                        pair = Some((add, remove));
                    }
                }else {
                    pair = Some((add, remove));
                }
            }
        } 
        if let Some(neg) = last_negative {
            let remove = values[neg];
            if let Some(pos) = (k .. n).find(|&i| { values[i] > 0}) {
                let add = values[pos];
                if let Some((max_add, max_remove)) = pair {
                    if max_remove.abs() * add.abs() > max_add.abs() * remove.abs() {
                        pair = Some((add, remove));
                    }
                }else {
                    pair = Some((add, remove));
                }
            }
        }
        if let Some((max_add, max_remove)) = pair {
            let result = result * pow_mod(max_remove, (modulo - 2) as usize, modulo) % modulo * max_add % modulo;
            println!("{}", (modulo + result) % modulo);
        }else {
            println!("{}", (modulo + result) % modulo);
        }
    }else {
        result = 1i64;
        for i in n - k .. n {
            result = result * values[i] % modulo;
        }
        println!("{}", (modulo + result) % modulo);
    }
}