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
    if (ma - mi <= 1) exit
  end do

  print "(i0)", ma

  contains

  logical function isok(x)
    ! 積がx以下になるペアがk個以上ある
    integer(8), intent(in) :: x
    integer(8) :: i, cnt, jmin, jmax, count_j, mi, ma, md, j
    cnt = 0
    jmax = n
    if (x < 0) then
      jmin = 1
    else
      jmin = n + 1
    end if
    do i = 1, n - 1
      if (a(i) >= 0) then
        ! a(i) * a(j) <= x となる最大のj > iを求める
        jmax = max(jmax, i)
        do while (jmax > i)
          if (a(jmax) * a(i) > x) then
            jmax = jmax - 1
          else
            exit
          end if
        end do
        count_j = jmax - i
      else
        ! a(i) * a(j) <= x となる最小のj > iを求める
        jmin = max(jmin, i + 1)
        if (x < 0) then
          do while (jmin <= n)
            if (a(jmin) * a(i) > x) then
              jmin = jmin + 1
            else
              exit
            end if
          end do
          count_j = n - (jmin - 1)
        else
          do while (jmin > i + 1)
            if (a(jmin - 1) * a(i) <= x) then
              jmin = jmin - 1
            else
              exit
            end if
          end do
          count_j = n - (jmin - 1)
          ! 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_j = n - (ma - 1)
        end if
      end if
      cnt = cnt + count_j
    end do
    isok = (cnt >= k)
  end function isok

  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