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 Kotlin (1.3.71) (judge verdict: Accepted)

import java.util.*

fun main(args: Array<String>) {
    val pw = java.io.PrintWriter(System.out)
    Problem.solve(Scanner(System.`in`), pw)
    pw.flush()
}

fun <A : Comparable<A>> min(a: A, b: A) = if (a < b) a else b
fun <A : Comparable<A>> max(a: A, b: A) = if (a > b) a else b

object Problem {
    fun solve(sc: Scanner, pw: java.io.PrintWriter) {
        val N = sc.next().toInt()
        val K = sc.next().toInt()
        val A = LongArray(N) { sc.next().toLong() }

        val AP = A.filter { it > 0 }.sortedBy { -it }.toLongArray() // positive
        val AN = A.filter { it <= 0 }.sorted().toLongArray() // negative
        val CN = AN.count()

        var ans = 1L

        var kp = min(K, AP.count())
        var kn = K - kp
        if (kn % 2 == 1) {
            //dprint("kp=$kp kn=$kn")
            //if (kp == 0 || kn + 1 > CN) {
            if (kp == 0) {
                // マイナスしかできないので絶対値の小さいほうから K 個
                AN.reversed().take(K).forEach {
                    ans *= it
                    ans += 1000000007L
                    ans %= 1000000007L
                }
                pw.println(ans)
                return
            } else if (K == N) {
                // すべて選ぶしかない
                A.forEach {
                    ans *= it
                    ans += 1000000007L
                    ans %= 1000000007L
                }
                pw.println(ans)
                return
            }
            kp--
            kn++
        }

        while (true) {
            //dprint("kp=$kp kn=$kn")
            if (kp < 2 || kn + 2 > CN) break
            val a1 = AP[kp - 2] * AP[kp - 1]
            val a2 = AN[kn] * AN[kn + 1]
            if (a1 > a2) break
            kp -= 2
            kn += 2
        }

        for (i in 0 until kp) {
            ans *= AP[i]
            ans %= 1000000007L
        }
        for (i in 0 until kn) {
            ans *= -AN[i]
            ans %= 1000000007L
        }
        pw.println(ans)
    }
}