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 Haskell (GHC 8.8.3) (judge verdict: Runtime Error)

import Control.Monad
import qualified Data.ByteString.Char8 as BS
import Data.Function
import Data.List
import Data.Maybe
import Data.Ord
import qualified Data.Vector as V
import qualified Data.Vector.Algorithms.Intro as VAIT
import qualified Data.Vector.Generic as VG
import qualified Data.Vector.Generic.Mutable as VGM
import qualified Data.Vector.Mutable as VM
import qualified Data.Vector.Unboxed as VU
--import qualified Data.Vector.Unboxed.Mutable as VUM

readInt = fst . fromJust . BS.readInt

readInteger = fst . fromJust . BS.readInteger

readIntList = map readInt . BS.words

readIntegerList = map readInteger . BS.words

getIntList = readIntList <$> BS.getLine

getIntegerList = readIntegerList <$> BS.getLine
--
--prod' :: VU.Vector Int -> Integer
--prod' = VU.product . VU.map fromIntegral

prod :: VU.Vector Int -> Int
prod = VU.foldl1' (\x y -> mod1G7(x * y))

sortVecOn :: (Ord a, VG.Vector v b) => (b -> a) -> v b -> v b
sortVecOn f vec = VG.create $ do
  vec <- VG.thaw vec
  VAIT.sortBy (compare `on` f) vec
  return vec

mod1G7 :: Int -> Int
mod1G7 n = n `mod` (10 ^ 9 + 7)

main :: IO ()
main = do
  [n, k] <- getIntList
  as <- getIntList
  let as' = VU.fromList as
  if k == n
    then print $ prod as'
    else do
      if VU.all (<= 0) as'
        then
          if odd k
            then print $ prod $ VU.take k $ sortVecOn Down as'
            else print $ prod $ VU.take k $ sortVecOn id as'
        else do
          let as'' = sortVecOn (\a -> (- (abs a))) as'
          let bs = VU.take k as''
          let minus = VU.length (VU.filter (\a -> a <= 0) bs)
          let s = prod bs
          if even minus
            then print s
            else do
              let bsr = VU.reverse bs
              let cs = VU.drop k as''
              let bs' = VU.filter (\b' -> b' < 0) bsr
              let cs' = VU.filter (\a -> a > 0) cs
              let re = VU.head bs'
              let ad = VU.head cs'
              let d = if VU.length cs' == 0 || VU.length bs' == 0 then 0 else (fromIntegral s) `div` (fromIntegral (re)) * (fromIntegral (ad))
              let bs'' = VU.filter (\b' -> b' > 0) bsr
              let cs'' = VU.filter (\a -> a < 0) cs
              let re' = VU.head bs'
              let ad' = VU.head cs'
              let d' = if VU.length cs'' == 0 || VU.length bs'' == 0 then 0 else (fromIntegral s) `div` (fromIntegral (re')) * (fromIntegral (ad'))
              let ans | d == 0 && d' == 0 = prod (VU.take k (VU.filter (\a -> a <= 0) (VU.reverse as')))
                      | d == 0 = d'
                      | d' == 0 = d
                      | rat > rat' = d
                      | otherwise = d'
                      where
                        rat = (fromIntegral ad) / (fromIntegral re)
                        rat' = (fromIntegral ad') / (fromIntegral re')
              print ans