Buggy python submission (verdict: Runtime Error):
# -*- coding: utf-8 -*-
#尺取り法

import numpy as np
n, k = map(int,input().split())
a = np.array(list(map(int,input().split())))
a.sort()
posi = a[a>0]
zero = a[a==0]
nega = a[a<0]
#print(posi)
# 2分探索, midより小さいものを数える
l = -10**18-1
r = 10**18+1
while r-l > 1:
    mid = (r+l)//2
    cnt = 0
    if mid >= 0:
        cnt += len(zero)*n

    # a.searchsorted(v, side="left"): a[i-1] < v <= a[i]であるvのindexを返す
    # a.searchsorted(v, side="right"): a[i-1] <= v < a[i]であるvのindexを返す

    cnt += a.searchsorted(mid//posi, side="right").sum()
    cnt += (n - a.searchsorted(-(-mid//nega), side="left")).sum()
    cnt -= np.count_nonzero(a*a <= mid)
    cnt //= 2
    #print("mid:", mid)
    #print("mid//posi:", mid//posi)
    #print("search:", a.searchsorted(mid//posi,side="right"))
    #print("-(-mid//nega):", -(-mid//nega))
    #print("search:", a.searchsorted(-(-mid//nega),side="left"))
    #print("nonzero_count:", np.count_nonzero(a*a<=mid))
    #print("count:", cnt)
    #print('-' * 20)
    if cnt >= k:
        r = mid
    else:
        l = mid
print(r)

Fixed submission:
# -*- coding: utf-8 -*-
#尺取り法

import numpy as np
n, k = map(int,input().split())
a = np.array(list(map(int,input().split())))
a.sort()
posi = a[a>0]
zero = a[a==0]
nega = a[a<0]
#print(posi)
# 2分探索, midより小さいものを数える
l = -10**18-1
r = 10**18+1
while r-l > 1:
    mid = (r+l)//2
    cnt = 0
    if mid >= 0:
        cnt += len(zero)*n

    # a.searchsorted(v, side="left"): a[i-1] < v <= a[i]であるvのindexを返す
    # a.searchsorted(v, side="right"): a[i-1] <= v < a[i]であるvのindexを返す

    cnt += a.searchsorted(mid//posi, side="right").sum()
    cnt += (n - a.searchsorted(-(-mid//nega), side="left")).sum()
    cnt -= np.count_nonzero(a*a <= mid)
    cnt //= 2
    #print("mid:", mid)
    #print("mid//posi:", mid//posi)
    #print("search:", a.searchsorted(mid//posi,side="right"))
    #print("-(-mid//nega):", -(-mid//nega))
    #print("search:", a.searchsorted(-(-mid//nega),side="left"))
    #print("nonzero_count:", np.count_nonzero(a*a<=mid))
    #print("count:", cnt)
    #print('-' * 20)
    if cnt >= k:
        r = mid
    else:
        l = mid
print(r)

Buggy python submission (verdict: Time Limit Exceeded):
from bisect import bisect_left, bisect_right
N, K = map(int, input().split())
A = sorted(list(map(int, input().split())))
 
negative_end = bisect_left(A, 0)
positive_start = bisect_right(A, 0)
 
positive_cnt = N - positive_start
negative_cnt = negative_end
zero_cnt = N - (positive_cnt + negative_cnt)
 
negative_pairs_cnt = positive_cnt * negative_cnt
zero_pairs_cnt = zero_cnt * (positive_cnt + negative_cnt) + (zero_cnt * (zero_cnt - 1) // 2)


# 答えが負の場合
if K <= negative_pairs_cnt:
    # にぶたん: X以下になるペアがK個以上あるか？
    ok, ng = 0, -10 ** 18
    while abs(ok - ng) > 1:
        X = (ok + ng) // 2
        or_higher_cnt, r = 0, positive_start
        for l in range(negative_end):
            while (r < N) and (A[l] * A[r] > X):
                r += 1
            or_higher_cnt += positive_cnt - (r - positive_start)
 
        if or_higher_cnt >= K:
            ok = X
        else:
            ng = X
 
    print(ok)

# 答えが0の場合
elif K <= negative_pairs_cnt + zero_pairs_cnt:
    print(0)
 
# 答えが正の場合
else:
    # にぶたん: X以下になるペアがK個以上あるか？
    K -= (negative_pairs_cnt + zero_pairs_cnt)
    ok, ng = 10 ** 18, 0
    while abs(ok - ng) > 1:
        X = (ok + ng) // 2
        or_higher_cnt = 0
 
        r = N - 1
        for l in range(positive_start, N):
            while (r < N) and (A[l] * A[r] > X) and (l < r):
                r -= 1
            or_higher_cnt += max(0, r - l)
 
        l = 0
        for r in range(negative_end - 1, -1, -1):
            while (l < N) and (A[l] * A[r] > X) and (l < r):
                l += 1
 
            or_higher_cnt += max(0, r - l)
 
        if or_higher_cnt >= K:
            ok = X
        else:
            ng = X
 
    print(ok)

Fixed submission:
# -*- coding: utf-8 -*-
#尺取り法

import numpy as np
n, k = map(int,input().split())
a = np.array(list(map(int,input().split())))
a.sort()
posi = a[a>0]
zero = a[a==0]
nega = a[a<0]
#print(posi)
# 2分探索, midより小さいものを数える
l = -10**18-1
r = 10**18+1
while r-l > 1:
    mid = (r+l)//2
    cnt = 0
    if mid >= 0:
        cnt += len(zero)*n

    # a.searchsorted(v, side="left"): a[i-1] < v <= a[i]であるvのindexを返す
    # a.searchsorted(v, side="right"): a[i-1] <= v < a[i]であるvのindexを返す

    cnt += a.searchsorted(mid//posi, side="right").sum()
    cnt += (n - a.searchsorted(-(-mid//nega), side="left")).sum()
    cnt -= np.count_nonzero(a*a <= mid)
    cnt //= 2
    #print("mid:", mid)
    #print("mid//posi:", mid//posi)
    #print("search:", a.searchsorted(mid//posi,side="right"))
    #print("-(-mid//nega):", -(-mid//nega))
    #print("search:", a.searchsorted(-(-mid//nega),side="left"))
    #print("nonzero_count:", np.count_nonzero(a*a<=mid))
    #print("count:", cnt)
    #print('-' * 20)
    if cnt >= k:
        r = mid
    else:
        l = mid
print(r)

Buggy python submission (verdict: Time Limit Exceeded):
# -*- coding: utf-8 -*-
#尺取り法

from bisect import bisect_left, bisect_right

def main():
    N, K =  [int(i) for i in input().split()]
    A =  sorted(list(map(int, input().split())))

    nega_end = bisect_left(A, 0)
    posi_start = bisect_right(A, 0)

    posi_cnt = N - posi_start
    nega_cnt = nega_end
    zero_cnt = N - (posi_cnt + nega_cnt)

    nega_pairs_cnt = posi_cnt * nega_cnt
    zero_pairs_cnt = zero_cnt * (posi_cnt + nega_cnt) + (zero_cnt * (zero_cnt-1) // 2)

    if K <= nega_pairs_cnt:
        ok, ng = 0, -10 ** 18

        while abs(ok - ng) > 1:

            X = (ok + ng) // 2
            or_higher_cnt, r = 0, posi_start

            for l in range(nega_end):
                while (r < N) and (A[l] * A[r] > X):
                    r += 1
                or_higher_cnt += posi_cnt - (r - posi_start)

            if or_higher_cnt >= K:
                ok = X
            else:
                ng = X
            #print(ok, ng)
        print(ok)

    elif nega_pairs_cnt < K <= nega_pairs_cnt + zero_pairs_cnt:
        print(0)
        return
    else:
        K -= (nega_pairs_cnt + zero_pairs_cnt)
        ok, ng = 10 ** 18, 0
        while abs(ok - ng) > 1:
            X = (ok + ng) // 2
            or_higher_cnt = 0
            r = N - 1
            for l in range(posi_start, N):
                while (r < N) and (A[l] * A[r] > X) and (l < r):
                    r -= 1
                or_higher_cnt += max(0, r - l)

            l = 0
            for r in range(nega_end - 1, -1, -1):
                while (l < N) and (A[l] * A[r] > X) and (l < r):
                    l += 1

                or_higher_cnt += max(0, r - l)

            if or_higher_cnt >= K:
                ok = X
            else:
                ng = X
        print(ok)
if __name__ == "__main__":
    main()


Fixed submission:
# -*- coding: utf-8 -*-
#尺取り法

import numpy as np
n, k = map(int,input().split())
a = np.array(list(map(int,input().split())))
a.sort()
posi = a[a>0]
zero = a[a==0]
nega = a[a<0]
#print(posi)
# 2分探索, midより小さいものを数える
l = -10**18-1
r = 10**18+1
while r-l > 1:
    mid = (r+l)//2
    cnt = 0
    if mid >= 0:
        cnt += len(zero)*n

    # a.searchsorted(v, side="left"): a[i-1] < v <= a[i]であるvのindexを返す
    # a.searchsorted(v, side="right"): a[i-1] <= v < a[i]であるvのindexを返す

    cnt += a.searchsorted(mid//posi, side="right").sum()
    cnt += (n - a.searchsorted(-(-mid//nega), side="left")).sum()
    cnt -= np.count_nonzero(a*a <= mid)
    cnt //= 2
    #print("mid:", mid)
    #print("mid//posi:", mid//posi)
    #print("search:", a.searchsorted(mid//posi,side="right"))
    #print("-(-mid//nega):", -(-mid//nega))
    #print("search:", a.searchsorted(-(-mid//nega),side="left"))
    #print("nonzero_count:", np.count_nonzero(a*a<=mid))
    #print("count:", cnt)
    #print('-' * 20)
    if cnt >= k:
        r = mid
    else:
        l = mid
print(r)

Buggy python submission (verdict: Runtime Error):
# -*- coding: utf-8 -*-
#尺取り法

from bisect import bisect_left, bisect_right

def main():
    N, K =  [int(i) for i in input().split()]
    A =  sorted(list(map(int, input().split())))

    nega_end = bisect_left(A, 0)
    posi_start = bisect_right(A, 0)

    posi_cnt = N - posi_start
    nega_cnt = nega_end
    zero_cnt = N - (posi_cnt + nega_cnt)

    nega_pairs_cnt = posi_cnt * nega_cnt
    zero_pairs_cnt = zero_cnt * (posi_cnt + nega_cnt) + (zero_cnt * (zero_cnt-1) // 2)

    if K <= nega_pairs_cnt:
        ok, ng = 0, -10 ** 18

        while abs(ok - ng) > 1:

            X = (ok + ng) // 2
            or_higher_cnt, r = 0, posi_start

            for l in range(nega_end):
                while (r < N) and (A[l] * A[r] > X):
                    r += 1
                or_higher_cnt += posi_cnt - (r - posi_start)

            if or_higher_cnt >= K:
                ok = X
            else:
                ng = X
            #print(ok, ng)
        print(ok)

    elif nega_pairs_cnt < K <= nega_pairs_cnt + zero_pairs_cnt:
        print(0)
        return
    else:
        K -= (nega_pairs_cnt + zero_pairs_cnt)        
        ok, ng = 0, 10 ** 18
        while abs(ok - ng) > 1:
            X = (ok + ng) // 2
            r = N - 1
            for l in range(posi_start, N):
                while (r < N) and (A[l] * A[r] > X) and (l < r):
                    r -= 1
                or_higher_cnt += max(0, r - l)

            l = 0
            for r in range(nega_end - 1, -1, -1):
                while (l < N) and (A[l] * A[r] > X) and (l < r):
                    l += 1

                or_higher_cnt += max(0, r - l)

            if or_higher_cnt >= K:
                ok = X
            else:
                ng = X

if __name__ == "__main__":
    main()


Fixed submission:
# -*- coding: utf-8 -*-
#尺取り法

import numpy as np
n, k = map(int,input().split())
a = np.array(list(map(int,input().split())))
a.sort()
posi = a[a>0]
zero = a[a==0]
nega = a[a<0]
#print(posi)
# 2分探索, midより小さいものを数える
l = -10**18-1
r = 10**18+1
while r-l > 1:
    mid = (r+l)//2
    cnt = 0
    if mid >= 0:
        cnt += len(zero)*n

    # a.searchsorted(v, side="left"): a[i-1] < v <= a[i]であるvのindexを返す
    # a.searchsorted(v, side="right"): a[i-1] <= v < a[i]であるvのindexを返す

    cnt += a.searchsorted(mid//posi, side="right").sum()
    cnt += (n - a.searchsorted(-(-mid//nega), side="left")).sum()
    cnt -= np.count_nonzero(a*a <= mid)
    cnt //= 2
    #print("mid:", mid)
    #print("mid//posi:", mid//posi)
    #print("search:", a.searchsorted(mid//posi,side="right"))
    #print("-(-mid//nega):", -(-mid//nega))
    #print("search:", a.searchsorted(-(-mid//nega),side="left"))
    #print("nonzero_count:", np.count_nonzero(a*a<=mid))
    #print("count:", cnt)
    #print('-' * 20)
    if cnt >= k:
        r = mid
    else:
        l = mid
print(r)