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)

// This code is generated by [cargo-atcoder](https://github.com/tanakh/cargo-atcoder)
// Original source code:
/*
use proconio::input;
use std::convert::{From, Into, TryInto};
use std::fmt::Display;
use std::marker::PhantomData;
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use typenum::Unsigned;
use typenum_promote::promote;

/// Finite field of prime `P`
///
/// `P` must be an instance of `typenum::Unsigned` and a prime number.
///
/// ```
/// use competitive::prelude::*;
///
/// type GF = competitive::gf::GF<promote!(1000000007)>;
///
/// let t = GF::new(2);
/// assert_eq!(t.pow(100).as_u64(), 976371285);
/// ```
///
#[derive(Debug, Default, PartialEq, Eq)]
pub struct GF<P>(pub u64, PhantomData<P>);

impl<P> Clone for GF<P> {
    fn clone(&self) -> Self {
        Self(self.0, PhantomData::<P>)
    }
}

impl<P> Copy for GF<P> {}

impl<P> Display for GF<P> {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl<P: Unsigned> GF<P> {
    pub fn new<T: TryInto<i64>>(v: T) -> Self {
        Self(
            v.try_into().ok().unwrap().rem_euclid(P::to_i64()) as u64,
            PhantomData::<P>,
        )
    }

    pub fn as_u64(&self) -> u64 {
        self.0
    }

    pub fn pow(self, mut r: u64) -> Self {
        let mut k = self;
        let mut ret = GF::<P>::new(1);
        while r > 0 {
            if r % 2 != 0 {
                ret = ret * k;
            }
            r /= 2;
            k = k * k;
        }
        ret
    }

    // This requires P is prime
    pub fn recip(self) -> Self {
        self.pow(P::to_u64() - 2)
    }
}

impl<P: Unsigned, T: Into<GF<P>>> Add<T> for GF<P> {
    type Output = Self;
    fn add(self, rhs: T) -> Self::Output {
        Self::new(self.0 + rhs.into().0)
    }
}

impl<P: Unsigned, T: Into<GF<P>>> AddAssign<T> for GF<P> {
    fn add_assign(&mut self, rhs: T) {
        *self = *self + rhs;
    }
}

impl<P: Unsigned, T: Into<GF<P>>> Sub<T> for GF<P> {
    type Output = Self;
    fn sub(self, rhs: T) -> Self::Output {
        Self::new(self.0 + P::to_u64() - rhs.into().0)
    }
}

impl<P: Unsigned, T: Into<GF<P>>> SubAssign<T> for GF<P> {
    fn sub_assign(&mut self, rhs: T) {
        *self = *self - rhs;
    }
}

impl<P: Unsigned, T: Into<GF<P>>> Mul<T> for GF<P> {
    type Output = Self;
    fn mul(self, rhs: T) -> Self::Output {
        Self::new(self.0 * rhs.into().0)
    }
}

impl<P: Unsigned, T: Into<GF<P>>> MulAssign<T> for GF<P> {
    fn mul_assign(&mut self, rhs: T) {
        *self = *self * rhs;
    }
}

impl<P: Unsigned, T: Into<GF<P>>> Div<T> for GF<P> {
    type Output = Self;
    fn div(self, rhs: T) -> Self::Output {
        self * rhs.into().recip()
    }
}

impl<P: Unsigned, T: Into<GF<P>>> DivAssign<T> for GF<P> {
    fn div_assign(&mut self, rhs: T) {
        *self = *self / rhs;
    }
}

// FIXME: Currently, rustc does not allow partial orphan instance
// Use trait when it will be stabilized
macro_rules! def_ops {
    ($ty:ty) => {
        impl<P: Unsigned> Add<GF<P>> for $ty {
            type Output = GF<P>;
            fn add(self, rhs: GF<P>) -> Self::Output {
                GF::<P>::new(self) + rhs
            }
        }
        impl<P: Unsigned> Sub<GF<P>> for $ty {
            type Output = GF<P>;
            fn sub(self, rhs: GF<P>) -> Self::Output {
                GF::<P>::new(self) - rhs
            }
        }
        impl<P: Unsigned> Mul<GF<P>> for $ty {
            type Output = GF<P>;
            fn mul(self, rhs: GF<P>) -> Self::Output {
                GF::<P>::new(self) * rhs
            }
        }
        impl<P: Unsigned> Div<GF<P>> for $ty {
            type Output = GF<P>;
            fn div(self, rhs: GF<P>) -> Self::Output {
                GF::<P>::new(self) / rhs
            }
        }
    };
}

def_ops!(i8);
def_ops!(i16);
def_ops!(i32);
def_ops!(i64);
def_ops!(isize);

def_ops!(u8);
def_ops!(u16);
def_ops!(u32);
def_ops!(u64);
def_ops!(usize);

impl<P: Unsigned> Neg for GF<P> {
    type Output = Self;
    fn neg(self) -> Self {
        Self::new(0) - self
    }
}

impl<P: Unsigned, T: TryInto<i64>> From<T> for GF<P> {
    fn from(v: T) -> Self {
        Self::new(v)
    }
}

type GFp = GF<promote!(1_000_000_007)>;

fn main() {
    input! {
        n: usize,
        k: usize,
        mut v: [i64; n]
    }
    v.sort();

    let mut vec = Vec::new();

    let mut flag = true;
    for i in 0..n {
        if v[i] < 0 {
            vec.push((-v[i], -1));
        } else if v[i] > 0 {
            vec.push((v[i], 1));
            flag = false;
        }
    }
    vec.sort_by(|(a, _), (b, _)| a.cmp(b));
    let aaa = &vec[0..k].iter().fold(0, |x, (a, _)| a + x);

    let mut ans = GFp::new(1);
    let mut count = 0;
    let mut kount = 0;
    let mut last_p = 0;
    let mut last_p0 = 0;
    let mut last_n = 0;
    let mut last_n0 = 0;
    let mut ff1 = false;
    let mut ff2 = false;
    while let Some((val, sign)) = vec.pop() {
        if count < k {
            ans *= val;
            if sign == 1 {
                last_p = val;
            } else {
                kount += 1;
                last_n = val;
            }
            count += 1;
        } else {
            if ff1 && ff2 {
                break;
            }
            if !ff1 && sign == 1 {
                ff1 = true;
                last_p0 = val;
            }
            if !ff2 && sign == -1 {
                ff2 = true;
                last_n0 = val;
            }
        }
    }
    if count < k {
        println!("{}", 0)
    } else if flag && k % 2 == 1 {
        println!("{}", GFp::new(-aaa))
    } else if kount % 2 == 0 {
        println!("{}", ans)
    } else {
        if ff1 && ff2 {
            let (x,y) = if last_p0*last_n > last_p*last_n0 {
                (last_p,last_p0)
            } else {
                (last_n,last_n0)
            };
            ans *= GFp::new(x).recip();
            ans *= y;
            println!("{}", ans)
        } else if !ff1 && ff2 {
            ans *= GFp::new(last_n).recip();
            ans *= last_n0;
            println!("{}", ans)
        } else if ff1 && !ff2 {
            ans *= GFp::new(last_p).recip();
            ans *= last_p0;
            println!("{}", ans)
        } else {
            println!("{}",0)
        }
        
    }
}
*/

fn main() {
    let exe = "/tmp/bin00B3E969";
    std::io::Write::write_all(&mut std::fs::File::create(exe).unwrap(), &decode(BIN)).unwrap();
    std::fs::set_permissions(exe, std::os::unix::fs::PermissionsExt::from_mode(0o755)).unwrap();
    std::process::exit(std::process::Command::new(exe).status().unwrap().code().unwrap())
}

fn decode(v: &str) -> Vec<u8> {
    let mut ret = vec![];
    let mut buf = 0;
    let mut tbl = vec![64; 256];
    for i in 0..64 { tbl[TBL[i] as usize] = i as u8; }
    for (i, c) in v.bytes().filter_map(|c| { let c = tbl[c as usize]; if c < 64 { Some(c) } else { None } }).enumerate() {
        match i % 4 {
            0 => buf = c << 2,
            1 => { ret.push(buf | c >> 4); buf = c << 4; }
            2 => { ret.push(buf | c >> 2); buf = c << 6; }
            3 => ret.push(buf | c),
            _ => unreachable!(),
        }
    }
    ret
}

const TBL: &'static [u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const BIN: &'static str = "<base64-encoded ELF executable removed>";