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: Wrong Answer)

// https://atcoder.jp/contests/abc173/tasks/abc173_e

use proconio::fastout;
use proconio::input;
use std::mem::swap;

const MOD: i64 = 1000000007;

#[fastout]
fn main() {
    input! {
        n: usize, k: usize,
        mut a_s: [i64; n],
    }
    let ans = if n == k || (a_s.iter().max().unwrap() < &0 && k % 2 != 0) {
        a_s.sort_unstable_by(|a, b| a.cmp(b));
        a_s[..k].iter().fold(1i64, |acc, &cur| (acc * cur) % MOD)
    } else {
        a_s.sort_unstable_by(|a, b| b.abs().cmp(&a.abs()));
        let acc = a_s[..k].iter().fold(1, |acc, &cur| (acc * cur) % MOD);
        if acc >= 0 {
            acc
        } else {
            a_s[k..].sort_unstable_by(|a, b| a.cmp(b));
            let acc = MOD + acc;
            let remove_n = a_s[..k].iter().filter(|&&x| x < 0).max();
            let add_p = a_s[k..].iter().next().filter(|&&x| x > 0);
            let remove_p = a_s[..k].iter().filter(|&&x| x > 0).min();
            let add_n = a_s.last().filter(|&&x| x < 0);
            match (remove_n, add_p, remove_p, add_n) {
                (Some(&a), Some(b), Some(&c), Some(d)) => {
                    if c * b < a * d {
                        ((acc * modinv(c, MOD)) % MOD * d) % MOD
                    } else {
                        ((acc * modinv(a, MOD)) % MOD * b) % MOD
                    }
                }
                (Some(&a), Some(b), _, _) => ((acc * modinv(a, MOD)) % MOD * b) % MOD,
                (_, _, Some(&c), Some(d)) => ((acc * modinv(c, MOD)) % MOD * d) % MOD,
                _ => 0,
            }
        }
    };
    println!("{}", ans);
}

fn modinv(mut a: i64, m: i64) -> i64 {
    let mut b = m;
    let mut u = 1;
    let mut v = 0;
    while b != 0 {
        let t = a / b;
        a -= t * b;
        swap(&mut a, &mut b);
        u -= t * v;
        swap(&mut u, &mut v);
    }
    u %= m;
    if u < 0 {
        u += m;
    }
    return u;
}