Problem:
Score: 400 points

Problem Statement

We have N integers A_1, A_2, ..., A_N.

There are \frac{N(N-1)}{2} ways to choose two of them and form a pair. If we compute the product of each of those pairs and sort the results in ascending order, what will be the K-th number in that list?

Constraints

All values in input are integers.

2 \leq N \leq 2 \times 10^5

1 \leq K \leq \frac{N(N-1)}{2}

-10^9 \leq A_i \leq 10^9\ (1 \leq i \leq N)

Input

Input is given from Standard Input in the following format:

N K
A_1 A_2 \dots A_N

Output

Print the answer.

Sample Input 1

4 3
3 3 -4 -2

Sample Output 1

-6

There are six ways to form a pair. The products of those pairs are 9, -12, -6, -12, -6, 8.

Sorting those numbers in ascending order, we have -12, -12, -6, -6, 8, 9. The third number in this list is -6.

Sample Input 2

10 40
5 4 3 2 -1 0 0 0 0 0

Sample Output 2

6

Sample Input 3

30 413
-170202098 -268409015 537203564 983211703 21608710 -443999067 -937727165 -97596546 -372334013 398994917 -972141167 798607104 -949068442 -959948616 37909651 0 886627544 -20098238 0 -948955241 0 -214720580 277222296 -18897162 834475626 0 -425610555 110117526 663621752 0

Sample Output 3

448283280358331064

Solution in Rust (1.15.1) (judge verdict: Accepted)

// This code is generated by [cargo-atcoder](https://github.com/tanakh/cargo-atcoder)
// Original source code:
/*
use competitive::prelude::*;
use competitive::binary_search::*;

const PRODUCT_MAX: i64 = 1e18 as i64 + 7;

// u[i] * v[j] <= productとなる(i,j)の数を求める
// u[i] * v[j]はi, jについて単調増加であると仮定
fn count_product_lte(u: &[i64], v: &[i64], product: &i64) -> usize {
    u.iter().map(
        |x| (binary_search(-1, v.len() as i64, |i| x * v[i as usize] <= *product) + 1) as usize
    ).fold(0, |a, b| a + b)
}

fn count_product_lte_same(u: &[i64], product: &i64) -> usize {
    u.iter().enumerate().map(
        |(i, x)| (binary_search(i as i64, u.len() as i64, |j| x * u[j as usize] <= *product)) as usize - i
    ).fold(0, |a, b| a + b)
}

fn main() {
    input! {
        n: usize,
        k: usize,
        a: [i64; n],
    }
    let mut nums = a;
    nums.sort();
    let first_zero_index = lower_bound(&nums, &0);
    let first_positive_index = upper_bound(&nums, &0);
    let neg_nums = &nums[0..first_zero_index];
    let pos_nums = &nums[first_positive_index..n];
    let neg_abs_nums: Vec<i64> = neg_nums.iter().rev().map(|i| i.abs()).collect();
    let zero_count = first_positive_index - first_zero_index;
    let neg_product_count = neg_nums.len() * pos_nums.len();
    let zero_product_count = if zero_count > 0 {
        zero_count * (zero_count - 1) / 2 + zero_count * (neg_nums.len() + pos_nums.len())
    } else { 0 };

    // x以下の積の個数, O(n)
    let count = |x: i64| -> usize{
        if x < 0 {
            count_product_lte(pos_nums, neg_nums, &x)
        } else if x == 0 {
            zero_product_count + neg_product_count
        } else {
            zero_product_count
                + neg_product_count
                + count_product_lte_same(pos_nums, &x)
                + count_product_lte_same(&neg_abs_nums, &x)
        }
    };
//    for n in -12..=9 {
//        println!("{} => {}", n, count(n));
//    }
    let ans = binary_search(-PRODUCT_MAX, PRODUCT_MAX, |x| count(x) < k) + 1;
    println!("{}", ans);
}
*/

fn main() {
    let exe = "/tmp/binF8AAC017";
    std::io::Write::write_all(&mut std::fs::File::create(exe).unwrap(), &decode(BIN)).unwrap();
    std::fs::set_permissions(exe, std::os::unix::fs::PermissionsExt::from_mode(0o755)).unwrap();
    std::process::exit(std::process::Command::new(exe).status().unwrap().code().unwrap())
}

fn decode(v: &str) -> Vec<u8> {
    let mut ret = vec![];
    let mut buf = 0;
    let mut tbl = vec![64; 256];
    for i in 0..64 { tbl[TBL[i] as usize] = i as u8; }
    for (i, c) in v.bytes().filter_map(|c| { let c = tbl[c as usize]; if c < 64 { Some(c) } else { None } }).enumerate() {
        match i % 4 {
            0 => buf = c << 2,
            1 => { ret.push(buf | c >> 4); buf = c << 4; }
            2 => { ret.push(buf | c >> 2); buf = c << 6; }
            3 => ret.push(buf | c),
            _ => unreachable!(),
        }
    }
    ret
}

const TBL: &'static [u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const BIN: &'static str = "<base64-encoded ELF executable removed>";