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)

const MOD: i64 = 1000000007;
#[derive(Default)]
//NOTE
//declare variables to reduce the number of parameters for dp and dfs etc.
struct Solver {}

impl Solver {
    fn solve(&mut self) {
        let stdin = std::io::stdin();
        let mut scn = Scanner {
            stdin: stdin.lock(),
        };
        let n: usize = scn.read();
        let k: usize = scn.read();
        let mut a: Vec<i64> = scn.vec(n);
        let mut left = vec![(1, 0, 0); n + 1];
        let mut right = vec![(1, 0, 0); n + 1];
        a.sort();
        a.reverse();
        left[1] = {
            if a[0] < 0 {
                (a[0].abs(), 1, 0)
            } else {
                (a[0], 0, 0)
            }
        };
        for (i, x) in a.iter().enumerate().skip(1) {
            left[i + 1].0 *= left[i].0.abs();
            left[i + 1].1 += left[i].1;
            left[i + 1].2 += left[i].2;
            left[i + 1].0 *= x.abs();
            if *x < 0 {
                left[i + 1].1 += 1;
            }
            if left[i + 1].0 > MOD {
                left[i + 1].2 += 1;
            }
            left[i + 1].0 %= MOD;
        }

        right[1] = {
            if a[n - 1] < 0 {
                (a[n - 1].abs(), 1, 0)
            } else {
                (a[n - 1], 0, 0)
            }
        };

        for (i, x) in a.iter().rev().enumerate().skip(1) {
            right[i + 1].0 *= right[i].0.abs();
            right[i + 1].1 += right[i].1;
            right[i + 1].2 += right[i].2;
            right[i + 1].0 *= x.abs();
            if *x < 0 {
                right[i + 1].1 += 1;
            }
            if right[i + 1].0 > MOD {
                right[i + 1].2 += 1;
            }
            right[i + 1].0 %= MOD;
        }

        //eprintln!("{:?}", left);
        //eprintln!("{:?}", right);
        let mut result = if a.contains(&0) {
            (0, 0, false)
        } else {
            ((1i64 << 60), 1000, true)
        };

        for i in 0..=k {
            let mut tmp = left[i].0 * right[k - i].0;
            let cnt = left[i].1 + right[k - i].1;
            let mut mod_cnt = left[i].2 + right[k - i].2;
            if tmp >= MOD {
                mod_cnt += 1;
                tmp %= MOD;
            }
            let neg = if cnt % 2 != 0 { true } else { false };
            //eprintln!("{} {} {}", tmp, neg, mod_cnt);
            if !neg {
                if !result.2 {
                    if mod_cnt >= result.1 {
                        if mod_cnt == result.1 {
                            if tmp > result.0 {
                                result = (tmp, mod_cnt, false);
                            }
                        } else {
                            result = (tmp, mod_cnt, false);
                        }
                    }
                } else {
                    result = (tmp, mod_cnt, false);
                }
            } else {
                if result.2 {
                    if mod_cnt <= result.1 {
                        if mod_cnt == result.1 {
                            if tmp < result.0 {
                                result = (tmp, mod_cnt, true);
                            }
                        } else {
                            result = (tmp, mod_cnt, true);
                        }
                    }
                }
            }
            //eprintln!("{:?}", result);
            //result = std::cmp::max(result, tmp);
        }
        if result.2 {
            result.0 *= -1;
        }
        while result.0 < 0 {
            result.0 += MOD;
        }
        eprintln!("{:?}", result);

        println!("{}", result.0 % MOD);
    }
}

fn main() {
    std::thread::Builder::new()
        .stack_size(64 * 1024 * 1024) // 64MB
        .spawn(|| {
            let mut solver = Solver::default();
            solver.solve()
        })
        .unwrap()
        .join()
        .unwrap();
}
pub mod utils {
    const DYX: [(isize, isize); 8] = [
        (0, 1),   //right
        (1, 0),   //down
        (0, -1),  //left
        (-1, 0),  //top
        (1, 1),   //down right
        (-1, 1),  //top right
        (1, -1),  //down left
        (-1, -1), //top left
    ];

    pub fn try_adj(y: usize, x: usize, dir: usize, h: usize, w: usize) -> Option<(usize, usize)> {
        let ny = y as isize + DYX[dir].0;
        let nx = x as isize + DYX[dir].1;
        if ny >= 0 && nx >= 0 {
            let ny = ny as usize;
            let nx = nx as usize;
            if ny < h && nx < w {
                Some((ny, nx))
            } else {
                None
            }
        } else {
            None
        }
    }
}

//snippet from kenkoooo
pub struct Scanner<R> {
    stdin: R,
}

impl<R: std::io::Read> Scanner<R> {
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .stdin
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n' || b == b'\r')
            .take_while(|&b| b != b' ' && b != b'\n' && b != b'\r')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn read_line(&mut self) -> String {
        use std::io::Read;
        let buf = self
            .stdin
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b'\n' || b == b'\r')
            .take_while(|&b| b != b'\n' && b != b'\r')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }

    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}