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)

#[allow(unused_imports)]
use {
   proconio::{fastout, input, marker::*},
   std::cmp::*,
   std::collections::*,
};

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

   if n == k {
      let mut ans = Mint::new(1);
      for i in 0..k {
         ans *= a[i];
      }
      println!("{}", ans);
      return;
   }

   let mut pos = vec![];
   let mut neg = vec![];
   for a in a {
      if a >= 0 {
         pos.push(a);
      } else {
         neg.push(-a);
      }
   }

   pos.sort_by(|a, b| b.cmp(a));
   neg.sort_by(|a, b| b.cmp(a));
   if pos.len() == 0 && k % 2 == 1 {
      neg.reverse();
      let mut ans = Mint::new(1);
      for i in 0..k {
         ans *= -neg[i];
      }
      println!("{}", ans);
      return;
   }
   let np = pos.len();
   let nn = pos.len();
   let mut l = min(k, np);
   let mut r = k - l;
   if r % 2 == 1 {
      l -= 1;
      r += 1;
   }
   loop {
      if l == 0 || r + 2 > nn {
         break;
      }
      if pos[l - 1] * pos[l - 2] < neg[r] * neg[r + 1] {
         l -= 2;
         r += 2;
      } else {
         break;
      }
   }
   let mut ans = Mint::new(1);
   for i in 0..l {
      ans *= pos[i];
   }
   for i in 0..r {
      ans *= neg[i];
   }
   println!("{}", ans);
}

const MOD: i64 = 1000000007;
#[derive(Copy, Clone)]
pub struct Mint {
   x: i64,
}
impl Mint {
   fn new(x: i64) -> Self {
      Mint {
         x: x.rem_euclid(MOD),
      }
   }
   fn pow(self, n: usize) -> Self {
      match n {
         0 => Mint::new(1),
         _ => {
            let mut a = self.pow(n >> 1);
            a *= a;
            if n & 1 == 1 {
               a *= self;
            }
            a
         }
      }
   }
   fn inv(self) -> Self { self.pow((MOD - 2) as usize) }
}
impl std::ops::Neg for Mint {
   type Output = Mint;
   fn neg(self) -> Self::Output { Self::new(-self.x) }
}
impl std::ops::AddAssign<Mint> for Mint {
   fn add_assign(&mut self, rhs: Self) {
      self.x += rhs.x;
      self.x %= MOD;
   }
}
impl std::ops::AddAssign<i64> for Mint {
   fn add_assign(&mut self, rhs: i64) { *self += Mint::new(rhs); }
}
impl std::ops::AddAssign<usize> for Mint {
   fn add_assign(&mut self, rhs: usize) { *self += Mint::new(rhs as i64); }
}
impl<T> std::ops::Add<T> for Mint
where
   Mint: std::ops::AddAssign<T>,
{
   type Output = Self;
   fn add(self, other: T) -> Self {
      let mut res = self;
      res += other;
      res
   }
}
impl std::ops::SubAssign<Mint> for Mint {
   fn sub_assign(&mut self, rhs: Self) {
      self.x -= rhs.x;
      if self.x < 0 {
         self.x += MOD;
      }
   }
}
impl std::ops::SubAssign<i64> for Mint {
   fn sub_assign(&mut self, rhs: i64) { *self -= Mint::new(rhs); }
}
impl std::ops::SubAssign<usize> for Mint {
   fn sub_assign(&mut self, rhs: usize) { *self -= Mint::new(rhs as i64); }
}
impl<T> std::ops::Sub<T> for Mint
where
   Mint: std::ops::SubAssign<T>,
{
   type Output = Self;
   fn sub(self, other: T) -> Self {
      let mut res = self;
      res -= other;
      res
   }
}
impl std::ops::MulAssign<Mint> for Mint {
   fn mul_assign(&mut self, rhs: Self) {
      self.x *= rhs.x;
      self.x %= MOD;
   }
}
impl std::ops::MulAssign<i64> for Mint {
   fn mul_assign(&mut self, rhs: i64) { *self *= Mint::new(rhs); }
}
impl std::ops::MulAssign<usize> for Mint {
   fn mul_assign(&mut self, rhs: usize) { *self *= Mint::new(rhs as i64); }
}
impl<T> std::ops::Mul<T> for Mint
where
   Mint: std::ops::MulAssign<T>,
{
   type Output = Self;
   fn mul(self, other: T) -> Self {
      let mut res = self;
      res *= other;
      res
   }
}
impl std::ops::DivAssign<Mint> for Mint {
   fn div_assign(&mut self, rhs: Self) { *self *= rhs.inv(); }
}
impl std::ops::DivAssign<i64> for Mint {
   fn div_assign(&mut self, rhs: i64) { *self /= Mint::new(rhs); }
}
impl std::ops::DivAssign<usize> for Mint {
   fn div_assign(&mut self, rhs: usize) { *self /= Mint::new(rhs as i64); }
}
impl<T> std::ops::Div<T> for Mint
where
   Mint: std::ops::DivAssign<T>,
{
   type Output = Self;
   fn div(self, other: T) -> Self {
      let mut res = self;
      res /= other;
      res
   }
}
impl<T> From<T> for Mint
where
   i64: From<T>,
{
   fn from(x: T) -> Mint { Mint::new(i64::from(x)) }
}
impl std::fmt::Display for Mint {
   fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.x) }
}
impl std::ops::Deref for Mint {
   type Target = i64;
   fn deref(&self) -> &Self::Target { &self.x }
}