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)]
#![allow(dead_code)]

use proconio::input;
use proconio::marker::{Bytes, Chars};
use std::collections::*;

fn main() {
    input! {
        n:usize,
        k:usize,
        a:[i64;n],
    }
    let modulo = 1e9 as i64 + 7;
    let num_zero = a.iter().filter(|&&x| x == 0).count();
    if n - num_zero < k {
        println!("{}", 0);
        return;
    }
    let mut plus = a.iter().filter(|&&x| x > 0).copied().collect::<Vec<_>>();
    let mut minus = a.iter().filter(|&&x| x < 0).copied().collect::<Vec<_>>();
    let all_minus = plus.len() == 0;
    let minus_odd = minus.len() % 2 != 0;
    let just_k = plus.len() + minus.len() == k;
    let is_not_plus = (all_minus && k % 2 != 0) || (just_k && minus_odd);
    if is_not_plus {
        //絶対0以下になる場合
        let ans = if num_zero == 0 {
            let mut cand = plus.iter().chain(minus.iter()).copied().collect::<Vec<_>>();
            cand.sort_by_key(|&x| x.abs());
            let mut res = cand.iter().take(k).fold(1, |acc, &x| acc * x % modulo);
            if res < 0 {
                res = (res % modulo + modulo) % modulo;
            }
            res
        } else {
            0
        };
        println!("{}", ans)
    } else {
        let mut k = k;
        plus.sort_by_key(|&x| -x);
        minus.sort();
        let ans = if k % 2 == 0 {
            1
        } else {
            k -= 1;
            plus.remove(0)
        };
        let mut cand = vec![];
        for i in 0.. {
            if 2 * i + 1 >= plus.len() {
                break;
            }
            cand.push(plus[2 * i] * plus[2 * i + 1]);
        }
        for i in 0.. {
            if 2 * i + 1 >= minus.len() {
                break;
            }
            cand.push(minus[2 * i] * minus[2 * i + 1]);
        }
        cand.sort_by_key(|x| -x);
        let ans = cand
            .iter()
            .take(k / 2)
            .fold(ans, |acc, &x| x % modulo * acc % modulo);
        let ans = if ans < 0 {
            (ans % modulo + modulo) % modulo
        } else {
            ans % modulo
        };
        println!("{}", ans)
    }
}