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 num::One;
use proconio::input;
use std::cmp::Reverse;
use std::iter::Product;
use std::ops::DivAssign;
use std::ops::Mul;
use std::ops::MulAssign;
use std::ops::Neg;

fn main() {
    input! {
        n: usize,
        k: usize,
        r#as: [i64; n],
    }

    let mut plus = vec![];
    let mut minus = vec![];
    let mut zero_exist = false;
    for a in r#as {
        if a > 0 {
            plus.push(a as u64);
        } else if a < 0 {
            minus.push(-a as u64);
        } else {
            zero_exist = true;
        }
    }

    let ans = if plus.len() + minus.len() < k {
        Zpz { repr: 0 }
    } else if plus.is_empty() && k % 2 == 1 {
        if zero_exist {
            Zpz { repr: 0 }
        } else {
            plus.sort_unstable();
            minus.sort_unstable();
            -plus
                .into_iter()
                .chain(minus)
                .map(Zpz::new)
                .take(k)
                .product::<Zpz>()
        }
    } else {
        plus.sort_unstable_by_key(|&a| Reverse(a));
        minus.sort_unstable();

        let mut ans = plus.iter().copied().take(k).map(Zpz::new).product::<Zpz>();
        let mut k = k.saturating_sub(plus.len());

        while k >= 2 && minus.len() >= 2 {
            let y1 = minus.pop().unwrap();
            let y2 = minus.pop().unwrap();
            ans *= Zpz::new(y1) * Zpz::new(y2);
            plus.push(y1);
            plus.push(y2);
            k -= 2;
        }
        plus.sort_unstable_by_key(|&a| Reverse(a));

        if k == 1 {
            let x = plus.pop().unwrap();
            let y1 = minus.pop().unwrap();
            let y2 = minus.pop().unwrap();
            ans *= Zpz::new(y1 * y2);
            ans /= Zpz::new(x);
        }

        while let (Some(x1), Some(x2), Some(y1), Some(y2)) =
            (plus.pop(), plus.pop(), minus.pop(), minus.pop())
        {
            if x1 * x2 >= y1 * y2 {
                break;
            }
            ans *= Zpz::new(y1 * y2);
            ans /= Zpz::new(x1 * x2);
        }
        ans
    };

    println!("{}", ans.repr);
}

const P: u64 = 1_000_000_007;

#[derive(Clone, Copy)]
struct Zpz {
    repr: u64,
}

impl Zpz {
    fn new(val: u64) -> Self {
        Self { repr: val % P }
    }

    fn inv(self) -> Self {
        num::traits::pow(self, 1_000_000_005)
    }
}

impl One for Zpz {
    fn one() -> Self {
        Self { repr: 1 }
    }
}

impl Neg for Zpz {
    type Output = Self;

    fn neg(self) -> Self {
        Self::new(P - self.repr)
    }
}

impl Mul for Zpz {
    type Output = Self;

    fn mul(self, rhs: Self) -> Self {
        Self::new(self.repr * rhs.repr)
    }
}

impl MulAssign for Zpz {
    fn mul_assign(&mut self, rhs: Self) {
        *self = *self * rhs
    }
}

impl DivAssign for Zpz {
    #[allow(clippy::suspicious_op_assign_impl)]
    fn div_assign(&mut self, rhs: Self) {
        *self *= rhs.inv();
    }
}

impl Product for Zpz {
    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
        iter.fold(Self::one(), Mul::mul)
    }
}