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)

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

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

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

   let mut ans = Mint::new(1);
   if n == k {
      for i in 0..k {
         ans *= a[i];
      }
      println!("{}", ans);
      return;
   }
   if pos.len() == 0 && k % 2 == 1 {
      a.sort_by(|a, b| b.cmp(a));
      for i in 0..k {
         ans *= a[i];
      }
      println!("{}", ans);
      return;
   }

   pos.sort_by(|a, b| b.cmp(a));
   neg.sort();
   let mut ans = Mint::new(1);
   let mut c = 0;
   let mut np = 0;
   let mut nn = 0;
   if k % 2 == 1 {
      ans *= pos[0];
      np += 1;
      c += 1;
   }
   while c < k {
      if nn + 1 >= neg.len() {
         ans *= pos[np];
         ans *= pos[np + 1];
         np += 2;
      } else if np + 1 >= pos.len() {
         ans *= neg[nn];
         ans *= neg[nn + 1];
         nn += 2;
      } else if neg[nn] * neg[nn + 1] < pos[np] * pos[np + 1] {
         ans *= pos[np];
         ans *= pos[np + 1];
         np += 2;
      } else {
         ans *= neg[nn];
         ans *= neg[nn + 1];
         nn += 2;
      }
      c += 2;
   }
   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 }
}
impl std::ops::DerefMut for Mint {
   fn deref_mut(&mut self) -> &mut Self::Target { &mut self.x }
}