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)

use std::io;
use std::io::prelude::*;
use std::io::BufReader;
use std::str::FromStr;

fn read_vec<T: FromStr>(s: String) -> Result<Vec<T>, T::Err> {
    s.split(' ').map(|x| x.parse()).collect()
}

fn main() {
    const M: i64 = 1000_000_000 + 7;
    let mut lines = BufReader::new(io::stdin()).lines().map(|l| l.unwrap());
    let nk: Vec<usize> = read_vec(lines.next().unwrap()).unwrap();
    let mut v: Vec<i64> = read_vec(lines.next().unwrap()).unwrap();
    if nk[0] == nk[1] {
        let mut ans = v.iter().fold(1, |acc, x| acc * (x % M) % M);
        ans = (ans + M) % M;
        println!("{}", ans);
        return;
    }

    v.sort_by_key(|x| {
        let y = x >> 31;
        y - (x ^ y) // 絶対値のマイナス
    });
    let (head, tail) = v.split_at(nk[1]);
    if head.iter().any(|&x| x == 0) {
        println!("0");
        return;
    }
    // そのまま積を求めれば良い単純な場合
    // headの中に奇数が偶数個存在する
    let simple = head.iter().filter(|&&c| c < 0).count() & 1 == 0;
    // 奇数が奇数個存在するとき
    if !simple {
        // a,bを交換すると、絶対値は(b/(-a))倍になる
        let a = *head.iter().filter(|&&c| c < 0).last().unwrap();
        let b = tail.iter().filter(|&&c| c >= 0).next().cloned();
        // c,dを交換すると、絶対値は((-d)/c)倍になる
        let c = head.iter().filter(|&&c| c >= 0).last().cloned();
        let d = tail.iter().filter(|&&c| c < 0).next().cloned();
        // b/(-a)と(-d)/cで大きい方をとる
        // (-d)/c > b/(-a)  <-> da>bc
        let (x, y) = match (a, b) {
            (a, Some(b)) => match (c, d) {
                (Some(c), Some(d)) if a * d > b * c => (c, d),
                _ => (a, b),
            },
            (_, None) => match (c, d) {
                (Some(c), Some(d)) => (c, d),
                _ => {
                    // 全部負の数だった
                    let ans = v
                        .iter()
                        .rev()
                        .take(nk[1])
                        .fold(1, |acc, x| acc * (x % M) % M);
                    println!("{}", (ans + M) % M);
                    return;
                }
            },
        };
        let i = v.iter().position(|&xx| xx == x).unwrap();
        v[i] = y;
    }
    let ans = v.iter().take(nk[1]).fold(1, |acc, x| acc * (x % M) % M);
    println!("{}", (ans + M) % M);
}