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 OCaml (4.10.0) (judge verdict: Runtime Error)

let split_string ?(pattern="") = Str.split @@ Str.regexp pattern
let n, k = Scanf.sscanf (read_line ()) "%d %d" @@ fun n k -> (n, k)
let a = read_line () |> split_string ~pattern:" " |> List.map int_of_string

let m_1e9 = int_of_float 1e9 + 7
let ( +^ ) x y = (x + y) mod m_1e9
let ( -^ ) x y = x - y + if x < y then m_1e9 else 0
let ( *^ ) x y = ((x mod m_1e9) * (y mod m_1e9)) mod m_1e9

let rec take res n acc = match (n, acc) with
  | (_, []) | (0, _) -> List.rev res
  | (i, x :: xs) -> take (x :: res) (n - 1) xs
let take = take []

let rec drop n acc = match (n, acc) with
  | (0, acc) -> acc
  | (_, []) -> []
  | (n, x :: xs) -> drop (n - 1) xs

let rec split a b = function
  | [] -> (List.sort compare a |> List.rev, List.sort compare b)
  | x :: rest when x > 0 -> split (x :: a) b rest
  | x :: rest -> split a (x :: b) rest
let plus, minus = split [] [] a

let rec two res = function
  | [] -> res
  | x :: [] -> (x, 1) :: res
  | x :: y :: rest -> two ((x, y) :: res) rest

let solve1 () = 
  let ps = two [] plus in
  let ms = two [] minus in
  let acc = (ps @ ms) |> List.sort (fun (a, b) (c, d) -> abs (c * d) - abs (a * b)) in
  let sum = List.fold_left (fun sum (a, b) -> sum *^ a *^ b) 1 @@ take (k / 2) acc in
  let rec g sum = function
    | [] -> failwith ""
    | (a, _) :: _ when a > 0 -> sum *^ a
    | _ :: rest -> g sum rest 
  in
  if k mod 2 = 1 then g sum (drop (k / 2) acc) else sum

let solve2 () =
  let rec take res n acc = match (n, acc) with
    | (_, []) | (0, _) -> List.rev res
    | (i, x :: xs) -> take (x :: res) (n - 1) xs in
  let take = take [] in
  let a = List.sort (fun a b -> abs a - abs b) a in
  List.fold_left ( *^ ) 1 @@ take k a

let f n = (n + m_1e9) mod m_1e9
  
let () =
  let p_len = List.length plus in
  Printf.printf "%d\n" @@ f @@
  if p_len >= k || (k - p_len) mod 2 = 0 then solve1 () else solve2 ()