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 Fortran (gfortran v4.8.4) (judge verdict: Accepted)

program main
  implicit none
  integer(8) :: n, k, mi, ma, md, i
  integer(8), allocatable :: a(:)
  read *, n, k
  allocate (a(n))
  read *, a(:)
  call quicksort(a)

  ! 積がthres以下になるペアがk個以上ある最小のthres
  mi = -2 * 10_8 ** 18  ! NG
  ma = 2 * 10_8 ** 18  ! OK
  do i = 1, 70
    md = mi + (ma - mi) / 2
    if (isok(md)) then
      ma = md
    else
      mi = md
    end if
  end do

  print "(i0)", ma

  contains

  logical function isok(x)
    ! 積がx以下になるペアがk個以上ある
    integer(8), intent(in) :: x
    integer(8) :: i, cnt
    cnt = 0
    do i = 1, n
      cnt = cnt + count_lower(i, x)
    end do
    isok = (cnt >= k)
  end function isok

  integer(8) function count_lower(i, x)
    ! a(i) * a(j) <= x となるj>iの数
    integer(8), intent(in) :: i, x
    integer(8) :: j, mi, md, ma
    if (a(i) >= 0) then
      ! a(i) * a(j) <= x となる最大のjを求める
      mi = i  ! ok
      ma = n + 1  ! ng
      do j = 1, 30
        md = mi + (ma - mi) / 2
        if (a(i) * a(md) <= x) then
          mi = md
        else
          ma = md
        end if
        if (ma - mi <= 1) exit
      end do
      count_lower = mi - i
    else
      ! count_lower = 0
      ! do j = i + 1, n
      !   if (a(i) * a(j) <= x) count_lower = count_lower + 1
      ! end do

      ! a(i) * a(j) <= x となる最小のjを求める
      mi = i  ! ng
      ma = n + 1  ! ok
      do j = 1, 30
        md = mi + (ma - mi) / 2
        if (a(i) * a(md) <= x) then
          ma = md
        else
          mi = md
        end if
        if (ma - mi <= 1) exit
      end do
      count_lower = n - (ma - 1)
    end if
  end function count_lower

  recursive subroutine quicksort(a)
    integer(8), intent(inout) :: a(:)
    integer(8) :: pivot, i, j, k, tmp, n
    real(8) :: r
    n = size(a)
    if (n <= 1) return
    i = 1
    j = n
    call random_number(r)
    k = 1 + floor(r * n)
    k = max(1_8, min(k, n))
    pivot = a(k)
    do
      do while (.not. pivot <= a(i))
        i = i + 1
      end do
      do while (.not. a(j) <= pivot)
        j = j - 1
      end do
      if (i >= j) exit
      tmp = a(i)
      a(i) = a(j)
      a(j) = tmp
      i = i + 1
      j = j - 1
    end do
    call quicksort(a(1:i - 1))
    call quicksort(a(j + 1:n))
  end subroutine quicksort
end program main