Buggy python submission (verdict: Time Limit Exceeded):
import numpy as np
import sys

input = sys.stdin.readline

n, k = [int(x) for x in input().split()]
A = np.array([int(a) for a in input().split()], dtype="int64")

A = np.sort(A)

# 積がc以下となる組み合わせの数を求める
def n_comb_lt(c):
    n_comb = 0
    # A[i] > 0であるA[i]について
    target = c // A[A > 0]  # target以下の値がA[i]の相方
    n_comb += sum(np.searchsorted(A, target, side="right"))

    # A[i] == 0であるA[i]について
    n_comb += n * len(A[A == 0]) if c >= 0 else 0

    # A[i] < 0であるA[i]について
    target = -(-c // A[A < 0])
    n_comb += sum(n - np.searchsorted(A, target, side="left"))

    # 組み合わせのうち、A[i]*A[i]となっているものを引いて、2で割る
    n_comb -= len(A[A * A <= c])
    n_comb //= 2

    return n_comb

ok = -10 ** 18 - 1
ng = 10 ** 18 + 1

# k番目の積は、積がm未満となる組み合わせがk個未満となる最大のm
# ←→積が(m-1)以下となる組み合わせがk個未満となる最大のm
while ng - ok > 1:
    mid = (ng + ok) // 2
    if n_comb_lt(mid - 1) < k:
        ok = mid
    else:
        ng = mid

print(ok)

Fixed submission:
import numpy as np
import sys

input = sys.stdin.readline

n, k = [int(x) for x in input().split()]
A = np.array([int(a) for a in input().split()], dtype="int64")

A = np.sort(A)

A_pos = A[A > 0]
A_neg = A[A < 0]
A_zero = A[A == 0]

# 積がc以下となる組み合わせの数を求める
def n_comb_lt(c):
    n_comb = 0
    # A[i] > 0であるA[i]について
    target = c // A_pos  # target以下の値がA[i]の相方
    n_comb += np.searchsorted(A, target, side="right").sum()

    # A[i] == 0であるA[i]について
    n_comb += n * len(A_zero) if c >= 0 else 0

    # A[i] < 0であるA[i]について
    target = -(-c // A_neg)
    n_comb += (n - np.searchsorted(A, target, side="left")).sum()

    # 組み合わせのうち、A[i]*A[i]となっているものを引いて、2で割る
    n_comb -= A[A * A <= c].size
    n_comb //= 2

    return n_comb

ok = -10 ** 18 - 1
ng = 10 ** 18 + 1

# k番目の積は、積がm未満となる組み合わせがk個未満となる最大のm
# ←→積が(m-1)以下となる組み合わせがk個未満となる最大のm
while ng - ok > 1:
    mid = (ng + ok) // 2
    if n_comb_lt(mid - 1) < k:
        ok = mid
    else:
        ng = mid

print(ok)

Buggy python submission (verdict: Time Limit Exceeded):
import sys

input = sys.stdin.readline

n, k = [int(x) for x in input().split()]
A = [int(a) for a in input().split()]

A.sort()

# 積がx未満となる組み合わせの数を求める
def n_comb_lt(x):
    n_comb = 0
    for i in range(n - 1): # A[0], A[1], ..., A[n-2]について
        # i < jであるjのうち、A[i] * A[j] < xとなるjの数を求める
        if A[i] > 0:
            if A[i] * A[i + 1] >= x:
                n_partner = 0
            elif A[i] * A[n - 1] < x:
                n_partner = n - 1 - i
            else:
                ok = i + 1
                ng = n - 1

                # ok >= 1, ng <= 200000 - 1
                # log2(200000) < 18
                # for _ in range(18):
                while ng - ok > 1:
                    mid = (ng + ok) // 2
                    if A[i] * A[mid] < x:
                        ok = mid
                    else:
                        ng = mid
                n_partner = ok - i
        else:
            if A[i] * A[i + 1] < x:
                n_partner = n - 1 - i
            elif A[i] * A[n - 1] >= x:
                n_partner = 0
            else:
                ng = i + 1
                ok = n - 1
                # ok >= 1, ng <= 200000 - 1
                # log2(200000) < 18
                # for _ in range(18):
                while ok - ng > 1:
                    mid = (ng + ok) // 2
                    if A[i] * A[mid] < x:
                        ok = mid
                    else:
                        ng = mid
                n_partner = n - 1 - ng
        n_comb += n_partner

    return n_comb


ok = -10 ** 18 - 1
ng = 10 ** 18 + 1

# for _ in range(62):
while ng - ok > 1:
    mid = (ng + ok) // 2
    if n_comb_lt(mid) < k:
        ok = mid
    else:
        ng = mid

print(ok)


Fixed submission:
import numpy as np
import sys

input = sys.stdin.readline

n, k = [int(x) for x in input().split()]
A = np.array([int(a) for a in input().split()], dtype="int64")

A = np.sort(A)

A_pos = A[A > 0]
A_neg = A[A < 0]
A_zero = A[A == 0]

# 積がc以下となる組み合わせの数を求める
def n_comb_lt(c):
    n_comb = 0
    # A[i] > 0であるA[i]について
    target = c // A_pos  # target以下の値がA[i]の相方
    n_comb += np.searchsorted(A, target, side="right").sum()

    # A[i] == 0であるA[i]について
    n_comb += n * len(A_zero) if c >= 0 else 0

    # A[i] < 0であるA[i]について
    target = -(-c // A_neg)
    n_comb += (n - np.searchsorted(A, target, side="left")).sum()

    # 組み合わせのうち、A[i]*A[i]となっているものを引いて、2で割る
    n_comb -= A[A * A <= c].size
    n_comb //= 2

    return n_comb

ok = -10 ** 18 - 1
ng = 10 ** 18 + 1

# k番目の積は、積がm未満となる組み合わせがk個未満となる最大のm
# ←→積が(m-1)以下となる組み合わせがk個未満となる最大のm
while ng - ok > 1:
    mid = (ng + ok) // 2
    if n_comb_lt(mid - 1) < k:
        ok = mid
    else:
        ng = mid

print(ok)

Buggy python submission (verdict: Time Limit Exceeded):
import sys

input = sys.stdin.readline

n, k = [int(x) for x in input().split()]
A = [int(a) for a in input().split()]

A.sort()

# 積がx未満となる組み合わせの数を求める
def n_comb_lt(x):
    n_comb = 0
    for i in range(n - 1): # A[0], A[1], ..., A[n-2]について
        # i < jであるjのうち、A[i] * A[j] < xとなるjの数を求める
        if A[i] > 0:
            if A[i] * A[i + 1] >= x:
                n_partner = 0
            elif A[i] * A[n - 1] < x:
                n_partner = n - 1 - i
            else:
                ok = i + 1
                ng = n - 1

                # ok >= 1, ng <= 200000 - 1
                # log2(200000) < 18
                for _ in range(18):
                # while ng - ok > 1:
                    mid = (ng + ok) // 2
                    if A[i] * A[mid] < x:
                        ok = mid
                    else:
                        ng = mid
                n_partner = ok - i
        else:
            if A[i] * A[i + 1] < x:
                n_partner = n - 1 - i
            elif A[i] * A[n - 1] >= x:
                n_partner = 0
            else:
                ng = i + 1
                ok = n - 1
                # ok >= 1, ng <= 200000 - 1
                # log2(200000) < 18
                for _ in range(18):
                # while ok - ng > 1:
                    mid = (ng + ok) // 2
                    if A[i] * A[mid] < x:
                        ok = mid
                    else:
                        ng = mid
                n_partner = n - 1 - ng
        n_comb += n_partner

    return n_comb


ok = -10 ** 18 - 1
ng = 10 ** 18 + 1

for _ in range(62):
# while ng - ok > 1:
    mid = (ng + ok) // 2
    if n_comb_lt(mid) < k:
        ok = mid
    else:
        ng = mid

print(ok)


Fixed submission:
import numpy as np
import sys

input = sys.stdin.readline

n, k = [int(x) for x in input().split()]
A = np.array([int(a) for a in input().split()], dtype="int64")

A = np.sort(A)

A_pos = A[A > 0]
A_neg = A[A < 0]
A_zero = A[A == 0]

# 積がc以下となる組み合わせの数を求める
def n_comb_lt(c):
    n_comb = 0
    # A[i] > 0であるA[i]について
    target = c // A_pos  # target以下の値がA[i]の相方
    n_comb += np.searchsorted(A, target, side="right").sum()

    # A[i] == 0であるA[i]について
    n_comb += n * len(A_zero) if c >= 0 else 0

    # A[i] < 0であるA[i]について
    target = -(-c // A_neg)
    n_comb += (n - np.searchsorted(A, target, side="left")).sum()

    # 組み合わせのうち、A[i]*A[i]となっているものを引いて、2で割る
    n_comb -= A[A * A <= c].size
    n_comb //= 2

    return n_comb

ok = -10 ** 18 - 1
ng = 10 ** 18 + 1

# k番目の積は、積がm未満となる組み合わせがk個未満となる最大のm
# ←→積が(m-1)以下となる組み合わせがk個未満となる最大のm
while ng - ok > 1:
    mid = (ng + ok) // 2
    if n_comb_lt(mid - 1) < k:
        ok = mid
    else:
        ng = mid

print(ok)

Buggy python submission (verdict: Time Limit Exceeded):
n, k = [int(x) for x in input().split()]
A = [int(a) for a in input().split()]

A.sort()

# 積がx未満となる組み合わせの数を求める
def n_comb_lt(x):
    n_comb = 0
    for i in range(n - 1): # A[0], A[1], ..., A[n-2]について
        # i < jであるjのうち、A[i] * A[j] < xとなるjの数を求める
        if A[i] > 0:
            if A[i] * A[i + 1] >= x:
                n_partner = 0
            elif A[i] * A[n - 1] < x:
                n_partner = n - 1 - i
            else:
                ok = i + 1
                ng = n - 1

                # ok >= 1, ng <= 200000 - 1
                # log2(200000) < 18
                # for _ in range(18):
                while ng - ok > 1:
                    mid = (ng + ok) // 2
                    if A[i] * A[mid] < x:
                        ok = mid
                    else:
                        ng = mid
                n_partner = ok - i
        else:
            if A[i] * A[i + 1] < x:
                n_partner = n - 1 - i
            elif A[i] * A[n - 1] >= x:
                n_partner = 0
            else:
                ng = i + 1
                ok = n - 1
                # ok >= 1, ng <= 200000 - 1
                # log2(200000) < 18
                # for _ in range(18):
                while ok - ng > 1:
                    mid = (ng + ok) // 2
                    if A[i] * A[mid] < x:
                        ok = mid
                    else:
                        ng = mid
                n_partner = n - 1 - ng
        n_comb += n_partner

    return n_comb


ok = -10 ** 18 - 1
ng = 10 ** 18 + 1

while ng - ok > 1:
    mid = (ng + ok) // 2
    if n_comb_lt(mid) < k:
        ok = mid
    else:
        ng = mid

print(ok)



Fixed submission:
import numpy as np
import sys

input = sys.stdin.readline

n, k = [int(x) for x in input().split()]
A = np.array([int(a) for a in input().split()], dtype="int64")

A = np.sort(A)

A_pos = A[A > 0]
A_neg = A[A < 0]
A_zero = A[A == 0]

# 積がc以下となる組み合わせの数を求める
def n_comb_lt(c):
    n_comb = 0
    # A[i] > 0であるA[i]について
    target = c // A_pos  # target以下の値がA[i]の相方
    n_comb += np.searchsorted(A, target, side="right").sum()

    # A[i] == 0であるA[i]について
    n_comb += n * len(A_zero) if c >= 0 else 0

    # A[i] < 0であるA[i]について
    target = -(-c // A_neg)
    n_comb += (n - np.searchsorted(A, target, side="left")).sum()

    # 組み合わせのうち、A[i]*A[i]となっているものを引いて、2で割る
    n_comb -= A[A * A <= c].size
    n_comb //= 2

    return n_comb

ok = -10 ** 18 - 1
ng = 10 ** 18 + 1

# k番目の積は、積がm未満となる組み合わせがk個未満となる最大のm
# ←→積が(m-1)以下となる組み合わせがk個未満となる最大のm
while ng - ok > 1:
    mid = (ng + ok) // 2
    if n_comb_lt(mid - 1) < k:
        ok = mid
    else:
        ng = mid

print(ok)

Buggy python submission (verdict: Time Limit Exceeded):
n, k = [int(x) for x in input().split()]
A = [int(a) for a in input().split()]

A.sort()

# 積がx未満となる組み合わせの数を求める
def n_prod_lt(x):
    n_prod = 0
    for i in range(n - 1): # A[0], A[1], ..., A[n-2]について
        n_prod += n_partner(i, x)
    return n_prod

# i > jであるjのうち、A[i] * A[j] < xとなるjの数
def n_partner(i, x):
    if A[i] > 0:
        if A[i] * A[i + 1] >= x:
            ans = 0
        elif A[i] * A[n - 1] < x:
            ans = n - 1 - i
        else:
            ok = i + 1
            ng = n - 1
            while ng - ok > 1:
                mid = (ng + ok) // 2
                if A[i] * A[mid] < x:
                    ok = mid
                else:
                    ng = mid
            ans = ok - i
    else:
        if A[i] * A[i + 1] < x:
            ans = n - 1 - i
        elif A[i] * A[n - 1] >= x:
            ans = 0
        else:
            ng = i + 1
            ok = n - 1
            while ok - ng > 1:
                mid = (ng + ok) // 2
                if A[i] * A[mid] < x:
                    ok = mid
                else:
                    ng = mid
            ans = n - 1 - ng
    return(ans)

ok = -10 ** 18 - 1
ng = 10 ** 18 + 1

while ng - ok > 1:
    mid = (ng + ok) // 2
    if n_prod_lt(mid) < k:
        ok = mid
    else:
        ng = mid

print(ok)


Fixed submission:
import numpy as np
import sys

input = sys.stdin.readline

n, k = [int(x) for x in input().split()]
A = np.array([int(a) for a in input().split()], dtype="int64")

A = np.sort(A)

A_pos = A[A > 0]
A_neg = A[A < 0]
A_zero = A[A == 0]

# 積がc以下となる組み合わせの数を求める
def n_comb_lt(c):
    n_comb = 0
    # A[i] > 0であるA[i]について
    target = c // A_pos  # target以下の値がA[i]の相方
    n_comb += np.searchsorted(A, target, side="right").sum()

    # A[i] == 0であるA[i]について
    n_comb += n * len(A_zero) if c >= 0 else 0

    # A[i] < 0であるA[i]について
    target = -(-c // A_neg)
    n_comb += (n - np.searchsorted(A, target, side="left")).sum()

    # 組み合わせのうち、A[i]*A[i]となっているものを引いて、2で割る
    n_comb -= A[A * A <= c].size
    n_comb //= 2

    return n_comb

ok = -10 ** 18 - 1
ng = 10 ** 18 + 1

# k番目の積は、積がm未満となる組み合わせがk個未満となる最大のm
# ←→積が(m-1)以下となる組み合わせがk個未満となる最大のm
while ng - ok > 1:
    mid = (ng + ok) // 2
    if n_comb_lt(mid - 1) < k:
        ok = mid
    else:
        ng = mid

print(ok)

Buggy python submission (verdict: Time Limit Exceeded):
n, k = [int(x) for x in input().split()]
A = [int(a) for a in input().split()]

A.sort()

# 積がx未満となる組み合わせの数を求める
def n_prod_lt(x):
    n_prod = 0
    for i in range(n - 1): # A[0], A[1], ..., A[n-2]について
        n_prod += n_partner(i, x)
    return n_prod

# i > jであるjのうち、A[i] * A[j] < xとなるjの数
def n_partner(i, x):
    if A[i] > 0:
        if A[i] * A[i + 1] >= x:
            ans = 0
        elif A[i] * A[n - 1] < x:
            ans = n - 1 - i
        else:
            ok = i + 1
            ng = n - 1
            while ng - ok > 1:
                mid = (ng + ok) // 2
                if A[i] * A[mid] < x:
                    ok = mid
                else:
                    ng = mid
            ans = ok - i
    else:
        if A[i] * A[i + 1] < x:
            ans = n - 1 - i
        elif A[i] * A[n - 1] >= x:
            ans = 0
        else:
            ng = i + 1
            ok = n - 1
            while ok - ng > 1:
                mid = (ng + ok) // 2
                if A[i] * A[mid] < x:
                    ok = mid
                else:
                    ng = mid
            ans = n - 1 - ng
    return(ans)

ok = -10 ** 18 - 1
ng = 10 ** 18 + 1

while ng - ok > 1:
    mid = (ng + ok) // 2
    if n_prod_lt(mid) < k:
        ok = mid
    else:
        ng = mid

print(ok)


Fixed submission:
import numpy as np
import sys

input = sys.stdin.readline

n, k = [int(x) for x in input().split()]
A = np.array([int(a) for a in input().split()], dtype="int64")

A = np.sort(A)

A_pos = A[A > 0]
A_neg = A[A < 0]
A_zero = A[A == 0]

# 積がc以下となる組み合わせの数を求める
def n_comb_lt(c):
    n_comb = 0
    # A[i] > 0であるA[i]について
    target = c // A_pos  # target以下の値がA[i]の相方
    n_comb += np.searchsorted(A, target, side="right").sum()

    # A[i] == 0であるA[i]について
    n_comb += n * len(A_zero) if c >= 0 else 0

    # A[i] < 0であるA[i]について
    target = -(-c // A_neg)
    n_comb += (n - np.searchsorted(A, target, side="left")).sum()

    # 組み合わせのうち、A[i]*A[i]となっているものを引いて、2で割る
    n_comb -= A[A * A <= c].size
    n_comb //= 2

    return n_comb

ok = -10 ** 18 - 1
ng = 10 ** 18 + 1

# k番目の積は、積がm未満となる組み合わせがk個未満となる最大のm
# ←→積が(m-1)以下となる組み合わせがk個未満となる最大のm
while ng - ok > 1:
    mid = (ng + ok) // 2
    if n_comb_lt(mid - 1) < k:
        ok = mid
    else:
        ng = mid

print(ok)