import sys

import bisect



read = sys.stdin.buffer.read

readline = sys.stdin.buffer.readline



in_n = lambda: int(readline())

in_nn = lambda: list(map(int, readline().split()))

in_nl = lambda: list(map(int, readline().split()))

in_na = lambda: list(map(int, read().split()))

in_s = lambda: readline().rstrip().decode('utf-8')



INF = 10**18





def binary_search(min_n, max_n, judge):



    while max_n - min_n != 1:

        tn = (min_n + max_n) // 2

        if judge(tn):

            max_n = tn

        else:

            min_n = tn



    return max_n





def main():

    N, K = in_nn()

    A = in_nl()



    Ap = []

    Am = []

    Nz = 0



    for i in range(N):

        if A[i] > 0:

            Ap.append(A[i])

        elif A[i] == 0:

            Nz += 1

        else:

            Am.append(A[i])



    Np = len(Ap)

    Nm = len(Am)



    m_count = Np * Nm

    z_count = Nz * (Np + Nm) + Nz * (Nz - 1) // 2

    # p_count = Np * (Np - 1) // 2 + Nm * (Nm - 1) // 2



    if K <= m_count:



        Ap.sort()

        Am.sort()



        def judge(tn):



            count = 0

            for i in range(Nm):

                search = -(-tn // Am[i])

                j = bisect.bisect_left(Ap, search)

                count += Np - j



            return count >= K



        ans = binary_search(-INF, -1, judge)



    elif K <= m_count + z_count:

        ans = 0

    else:



        Ap.sort()

        Am = sorted([-a for a in Am])



        def judge(tn):



            count = 0

            for i in range(Np):

                search = tn // Ap[i]

                j = bisect.bisect_right(Ap, search)

                count += max(0, j - i - 1)



            for i in range(Nm):

                search = tn // Am[i]

                j = bisect.bisect_right(Am, search)

                count += max(0, j - i - 1)



            return count >= (K - m_count - z_count)



        ans = binary_search(1, INF, judge)



    print(ans)





if __name__ == '__main__':

    main()

import sys

import numpy as np

from numba import njit



read = sys.stdin.buffer.read

readline = sys.stdin.buffer.readline



in_n = lambda: int(readline())

in_nn = lambda: list(map(int, readline().split()))

in_nl = lambda: list(map(int, readline().split()))

in_na = lambda: list(map(int, read().split()))

in_s = lambda: readline().rstrip().decode('utf-8')





@njit('(i8,i8,i4[:],i4[:],i8,i8)', cache=True)

def judge1(tn, K, Ap, Am, Nm, Np):



    count = 0

    for i in range(Nm):

        search = -(-tn // -Am[i])

        j = np.searchsorted(Ap, search, side='left')

        count += Np - j



    return count >= K





@njit('(i8,i8,i4[:],i4[:],i8,i8,i8,i8)', cache=True)

def judge2(tn, K, Ap, Am, Nm, Np, m_count, z_count):



    count = 0

    for i in range(Np):

        search = tn // Ap[i]

        j = np.searchsorted(Ap, search, side='right')

        count += max(0, j - i - 1)



    for i in range(Nm):

        search = tn // Am[i]

        j = np.searchsorted(Am, search, side='right')

        count += max(0, j - i - 1)



    return count >= (K - m_count - z_count)





@njit('(i8,i8,i4[:],i4[:],i8,)', cache=True)

def solve(N, K, Ap, Am, Nz):



    INF = 10**18

    Np = Ap.size

    Nm = Am.size



    m_count = Np * Nm

    z_count = Nz * (Np + Nm) + Nz * (Nz - 1) // 2



    if K <= m_count:



        min_n, max_n = -INF, -1

        while max_n - min_n != 1:

            tn = (min_n + max_n) // 2

            if judge1(tn, K, Ap, Am, Nm, Np):

                max_n = tn

            else:

                min_n = tn



        ans = max_n



    elif K <= m_count + z_count:

        ans = 0



    else:



        min_n, max_n = 1, INF

        while max_n - min_n != 1:

            tn = (min_n + max_n) // 2

            if judge2(tn, K, Ap, Am, Nm, Np, m_count, z_count):

                max_n = tn

            else:

                min_n = tn



        ans = max_n



    return ans





def main():

    N, K = in_nn()

    A = in_nl()

    Ap, Am = [], []

    Nz = 0



    for i in range(N):

        if A[i] > 0:

            Ap.append(A[i])

        elif A[i] == 0:

            Nz += 1

        else:

            Am.append(A[i])



    Ap = np.array(sorted(Ap), np.int32)

    Am = np.array(sorted([-a for a in Am]), np.int32)



    print((solve(N, K, Ap, Am, Nz)))





if __name__ == '__main__':

    main()

import sys
import bisect

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
in_n = lambda: int(readline())
in_nn = lambda: list(map(int, readline().split()))
in_nl = lambda: list(map(int, readline().split()))
in_na = lambda: list(map(int, read().split()))
in_s = lambda: readline().rstrip().decode("utf-8")
INF = 10**18


def binary_search(min_n, max_n, judge):
    while max_n - min_n != 1:
        tn = (min_n + max_n) // 2
        if judge(tn):
            max_n = tn
        else:
            min_n = tn
    return max_n


def main():
    N, K = in_nn()
    A = in_nl()
    Ap = []
    Am = []
    Nz = 0
    for i in range(N):
        if A[i] > 0:
            Ap.append(A[i])
        elif A[i] == 0:
            Nz += 1
        else:
            Am.append(A[i])
    Np = len(Ap)
    Nm = len(Am)
    m_count = Np * Nm
    z_count = Nz * (Np + Nm) + Nz * (Nz - 1) // 2
    # p_count = Np * (Np - 1) // 2 + Nm * (Nm - 1) // 2
    if K <= m_count:
        Ap.sort()
        Am.sort()

        def judge(tn):
            count = 0
            for i in range(Nm):
                search = -(-tn // Am[i])
                j = bisect.bisect_left(Ap, search)
                count += Np - j
            return count >= K

        ans = binary_search(-INF, -1, judge)
    elif K <= m_count + z_count:
        ans = 0
    else:
        Ap.sort()
        Am = sorted([-a for a in Am])

        def judge(tn):
            count = 0
            for i in range(Np):
                search = tn // Ap[i]
                j = bisect.bisect_right(Ap, search)
                count += max(0, j - i - 1)
            for i in range(Nm):
                search = tn // Am[i]
                j = bisect.bisect_right(Am, search)
                count += max(0, j - i - 1)
            return count >= (K - m_count - z_count)

        ans = binary_search(1, INF, judge)
    print(ans)


if __name__ == "__main__":
    main()

import sys
import numpy as np
from numba import njit

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
in_n = lambda: int(readline())
in_nn = lambda: list(map(int, readline().split()))
in_nl = lambda: list(map(int, readline().split()))
in_na = lambda: list(map(int, read().split()))
in_s = lambda: readline().rstrip().decode("utf-8")


@njit("(i8,i8,i4[:],i4[:],i8,i8)", cache=True)
def judge1(tn, K, Ap, Am, Nm, Np):
    count = 0
    for i in range(Nm):
        search = -(-tn // -Am[i])
        j = np.searchsorted(Ap, search, side="left")
        count += Np - j
    return count >= K


@njit("(i8,i8,i4[:],i4[:],i8,i8,i8,i8)", cache=True)
def judge2(tn, K, Ap, Am, Nm, Np, m_count, z_count):
    count = 0
    for i in range(Np):
        search = tn // Ap[i]
        j = np.searchsorted(Ap, search, side="right")
        count += max(0, j - i - 1)
    for i in range(Nm):
        search = tn // Am[i]
        j = np.searchsorted(Am, search, side="right")
        count += max(0, j - i - 1)
    return count >= (K - m_count - z_count)


@njit("(i8,i8,i4[:],i4[:],i8,)", cache=True)
def solve(N, K, Ap, Am, Nz):
    INF = 10**18
    Np = Ap.size
    Nm = Am.size
    m_count = Np * Nm
    z_count = Nz * (Np + Nm) + Nz * (Nz - 1) // 2
    if K <= m_count:
        min_n, max_n = -INF, -1
        while max_n - min_n != 1:
            tn = (min_n + max_n) // 2
            if judge1(tn, K, Ap, Am, Nm, Np):
                max_n = tn
            else:
                min_n = tn
        ans = max_n
    elif K <= m_count + z_count:
        ans = 0
    else:
        min_n, max_n = 1, INF
        while max_n - min_n != 1:
            tn = (min_n + max_n) // 2
            if judge2(tn, K, Ap, Am, Nm, Np, m_count, z_count):
                max_n = tn
            else:
                min_n = tn
        ans = max_n
    return ans


def main():
    N, K = in_nn()
    A = in_nl()
    Ap, Am = [], []
    Nz = 0
    for i in range(N):
        if A[i] > 0:
            Ap.append(A[i])
        elif A[i] == 0:
            Nz += 1
        else:
            Am.append(A[i])
    Ap = np.array(sorted(Ap), np.int32)
    Am = np.array(sorted([-a for a in Am]), np.int32)
    print((solve(N, K, Ap, Am, Nz)))


if __name__ == "__main__":
    main()

-import bisect +import numpy as np +from numba import njit -INF = 10**18 -def binary_search(min_n, max_n, judge): -    while max_n - min_n != 1: -        tn = (min_n + max_n) // 2 -        if judge(tn): -            max_n = tn -        else: -            min_n = tn -    return max_n +@njit("(i8,i8,i4[:],i4[:],i8,i8)", cache=True) +def judge1(tn, K, Ap, Am, Nm, Np): +    count = 0 +    for i in range(Nm): +        search = -(-tn // -Am[i]) +        j = np.searchsorted(Ap, search, side="left") +        count += Np - j +    return count >= K + + +@njit("(i8,i8,i4[:],i4[:],i8,i8,i8,i8)", cache=True) +def judge2(tn, K, Ap, Am, Nm, Np, m_count, z_count): +    count = 0 +    for i in range(Np): +        search = tn // Ap[i] +        j = np.searchsorted(Ap, search, side="right") +        count += max(0, j - i - 1) +    for i in range(Nm): +        search = tn // Am[i] +        j = np.searchsorted(Am, search, side="right") +        count += max(0, j - i - 1) +    return count >= (K - m_count - z_count) + + +@njit("(i8,i8,i4[:],i4[:],i8,)", cache=True) +def solve(N, K, Ap, Am, Nz): +    INF = 10**18 +    Np = Ap.size +    Nm = Am.size +    m_count = Np * Nm +    z_count = Nz * (Np + Nm) + Nz * (Nz - 1) // 2 +    if K <= m_count: +        min_n, max_n = -INF, -1 +        while max_n - min_n != 1: +            tn = (min_n + max_n) // 2 +            if judge1(tn, K, Ap, Am, Nm, Np): +                max_n = tn +            else: +                min_n = tn +        ans = max_n +    elif K <= m_count + z_count: +        ans = 0 +    else: +        min_n, max_n = 1, INF +        while max_n - min_n != 1: +            tn = (min_n + max_n) // 2 +            if judge2(tn, K, Ap, Am, Nm, Np, m_count, z_count): +                max_n = tn +            else: +                min_n = tn +        ans = max_n +    return ans -    Ap = [] -    Am = [] +    Ap, Am = [], [] -    Np = len(Ap) -    Nm = len(Am) -    m_count = Np * Nm -    z_count = Nz * (Np + Nm) + Nz * (Nz - 1) // 2 -    # p_count = Np * (Np - 1) // 2 + Nm * (Nm - 1) // 2 -    if K <= m_count: -        Ap.sort() -        Am.sort() - -        def judge(tn): -            count = 0 -            for i in range(Nm): -                search = -(-tn // Am[i]) -                j = bisect.bisect_left(Ap, search) -                count += Np - j -            return count >= K - -        ans = binary_search(-INF, -1, judge) -    elif K <= m_count + z_count: -        ans = 0 -    else: -        Ap.sort() -        Am = sorted([-a for a in Am]) - -        def judge(tn): -            count = 0 -            for i in range(Np): -                search = tn // Ap[i] -                j = bisect.bisect_right(Ap, search) -                count += max(0, j - i - 1) -            for i in range(Nm): -                search = tn // Am[i] -                j = bisect.bisect_right(Am, search) -                count += max(0, j - i - 1) -            return count >= (K - m_count - z_count) - -        ans = binary_search(1, INF, judge) -    print(ans) +    Ap = np.array(sorted(Ap), np.int32) +    Am = np.array(sorted([-a for a in Am]), np.int32) +    print((solve(N, K, Ap, Am, Nz)))