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::collections::BinaryHeap;
use std::cmp::Reverse;

fn main() {
    const MOD: isize = 1_000_000_007;

    let [n, k]: [usize; 2] = {
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        let mut iter = buf.split_whitespace();
        [
            iter.next().unwrap().parse().unwrap(),
            iter.next().unwrap().parse().unwrap(),
        ]
    };
    let a: Vec<isize> = {
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        let iter = buf.split_whitespace();
        iter.map(|x| x.parse().unwrap()).collect()
    };

    let mut minus = BinaryHeap::new();
    let mut plus = BinaryHeap::new();
    for i in 0..n {
        if a[i] < 0 {
            minus.push(Reverse(a[i]));
        } else {
            plus.push(a[i]);
        }
    }

    if k % 2 == 1 && plus.len() == 0 {
        let mut minus: BinaryHeap<_> = minus.iter().map(|x| x.0).collect();
        let mut plus: BinaryHeap<_> = plus.iter().map(|x| Reverse(x)).collect();
        let mut ans = 1;
        for _ in 0..k {
            match minus.pop() {
                Some(w) => {
                    match plus.pop() {
                        Some(Reverse(x)) => {
                            if w.abs() < x.abs() {
                                ans = ans * (w + MOD) % MOD;
                                plus.push(Reverse(x));
                            } else {
                                ans = ans * x % MOD;
                                minus.push(w);
                            }
                        },
                        None => {
                            ans = ans * (w + MOD) % MOD;
                        },
                    }
                },
                None => {
                    ans = ans * plus.pop().unwrap().0 % MOD;
                }
            }
        }
        println!("{}", ans);
    } else {
        let mut ans = 1;
        let mut minus_flag = false;
        for i in 0..k {
            if minus_flag {
                ans = ans * (minus.pop().unwrap().0 + MOD) % MOD;
                minus_flag = false;
                continue;
            }
            match minus.pop() {
                Some(Reverse(w)) => {
                    match minus.pop() {
                        Some(Reverse(x)) => {
                            match plus.pop() {
                                Some(y) => {
                                    match plus.pop() {
                                        Some(z) => {
                                            if i < k - 1 && w * x >= y * z {
                                                ans = ans * (w + MOD) % MOD;
                                                minus_flag = true;
                                                minus.push(Reverse(x));
                                                plus.push(y);
                                                plus.push(z);
                                            } else {
                                                ans = ans * y % MOD;
                                                minus.push(Reverse(w));
                                                minus.push(Reverse(x));
                                                plus.push(z);
                                            }
                                        },
                                        None => {
                                            if i == k - 1 {
                                                ans = ans * y % MOD;
                                            } else {
                                                ans = ans * (w + MOD) % MOD;
                                                minus_flag = true;
                                                minus.push(Reverse(x));
                                                plus.push(y); 
                                            }
                                        },
                                    }
                                },
                                None => {
                                    ans = ans * (w + MOD) % MOD;
                                    minus_flag = true;
                                    minus.push(Reverse(x));
                                },
                            }
                        },
                        None => {
                            match plus.pop() {
                                Some(y) => {
                                    ans = ans * y % MOD;
                                    minus.push(Reverse(w));
                                },
                                None => {
                                    ans = ans * (w + MOD) % MOD;
                                },
                            }
                        },
                    }
                },
                None => {
                    ans = ans * plus.pop().unwrap() % MOD;
                },
            }
        }
        println!("{}", ans);
    }
}