Buggy python submission (verdict: Time Limit Exceeded):
from sys import stdin
import numpy as np
def main():
    #入力
    readline=stdin.readline
    n,k=map(int,readline().split())
    a=np.array(readline().strip().split(),dtype="int64")
    
    a.sort()
    neg=a[a<0]
    zero=a[a==0]
    pos=a[a>0]
    l=-10**18-1
    r=10**18
    while l<r-1:
        x=(l+r)//2
        cnt=0
        if len(neg)>0:
            cnt+=(len(a)-np.searchsorted(a,(x+neg+1)//neg)).sum()
            for i in range(len(neg)):
                if neg[i]**2<=x:
                    cnt-=1
        if len(zero)>0:
            if x>=0:
                cnt+=(len(a)-1)*len(zero)
        if len(pos)>0:
            cnt+=np.searchsorted(a,x//pos,side="right").sum()
            for i in range(len(pos)):
                if pos[i]**2<=x:
                    cnt-=1

        cnt//=2
        if cnt>=k: r=x
        else: l=x

    print(r)

if __name__=="__main__":
    main()

Fixed submission:
from sys import stdin
def main():
    readline=stdin.readline
    N,K=map(int,readline().split())
    A=list(map(int,readline().split()))
    A.sort()

    #符号が - → 0 , 0 → + となるindexを求める
    index=[len(A),len(A)]
    mode=0
    for i in range(N):
        if mode==0:
            if A[i]==0:
                index[0]=i
                mode=1
            elif A[i]>0:
                index[0],index[1]=i,i
                break
        else:
            if A[i]>0:
                index[1]=i
                break

    #二分探索
    l=-10**18
    r=10**18+1
    while(l<r-1):
        x=(l+r)//2
        count=0

        #尺取り法
        if x>0:
            now_j=index[0]
            for i in range(index[0]):  #A[i]<0
                for j in range(now_j,-1,-1):
                    if A[i]*A[j-1]>=x:
                        now_j=j
                        count+=len(A)-now_j
                        if now_j<=i:
                            count-=1
                        break
                else:
                    now_j=0
                    count+=len(A)
                    count-=1

            for i in range(index[0],index[1]):  #A[i]=0
                if x>0:
                    count+=len(A)-1
                else:
                    break
            
            now_j=index[0]
            for i in range(len(A)-1,index[1]-1,-1):
                for j in range(now_j,len(A)):
                    if A[i]*A[j]>=x:
                        now_j=j
                        count+=now_j
                        if now_j>=i+1:
                            count-=1
                        break
                else:
                    now_j=len(A)
                    count+=len(A)
                    count-=1

        else:
            now_j=len(A)
            for i in range(index[0]-1,-1,-1):  #A[i]<0
                for j in range(now_j,-1,-1):
                    if A[i]*A[j-1]>=x:
                        now_j=j
                        count+=len(A)-now_j
                        if now_j<=i:
                            count-=1
                        break
            
            now_j=0
            for i in range(index[1],len(A)):
                for j in range(now_j,len(A)):
                    if A[i]*A[j]>=x:
                        now_j=j
                        count+=now_j
                        if now_j>=i+1:
                            count-=1
                        break

        count//=2
        if count<K:
            l=x
        else:
            r=x

    print(l)

if __name__=="__main__":
    main()

Buggy python submission (verdict: Time Limit Exceeded):
import sys
input=sys.stdin.readline
def main():
    N,K=map(int,input().split())
    A=list(map(int,input().split()))
    A.sort()

    left_target=-10**18
    right_target=10**18+1
    while left_target<right_target-1:
        mid_target=(left_target+right_target)//2
        count=0
        for i in range(N):
            a=A[i]
            if a<0:
                left_index=-1
                right_index=N
                while left_index<right_index-1:
                    mid_index=(left_index+right_index)//2
                    if a*A[mid_index]>=mid_target:
                        left_index=mid_index
                    else:
                        right_index=mid_index
                count+=N-(left_index+1)
            else:
                left_index=-1
                right_index=N
                while left_index<right_index-1:
                    mid_index=(left_index+right_index)//2
                    if a*A[mid_index]<mid_target:
                        left_index=mid_index
                    else:
                        right_index=mid_index
                count+=left_index+1

            if a*a<mid_target:
                count-=1
        count//=2
        if count<K:
            left_target=mid_target
        else:
            right_target=mid_target
    print(left_target)

if __name__=="__main__":
    main()

Fixed submission:
from sys import stdin
def main():
    readline=stdin.readline
    N,K=map(int,readline().split())
    A=list(map(int,readline().split()))
    A.sort()

    #符号が - → 0 , 0 → + となるindexを求める
    index=[len(A),len(A)]
    mode=0
    for i in range(N):
        if mode==0:
            if A[i]==0:
                index[0]=i
                mode=1
            elif A[i]>0:
                index[0],index[1]=i,i
                break
        else:
            if A[i]>0:
                index[1]=i
                break

    #二分探索
    l=-10**18
    r=10**18+1
    while(l<r-1):
        x=(l+r)//2
        count=0

        #尺取り法
        if x>0:
            now_j=index[0]
            for i in range(index[0]):  #A[i]<0
                for j in range(now_j,-1,-1):
                    if A[i]*A[j-1]>=x:
                        now_j=j
                        count+=len(A)-now_j
                        if now_j<=i:
                            count-=1
                        break
                else:
                    now_j=0
                    count+=len(A)
                    count-=1

            for i in range(index[0],index[1]):  #A[i]=0
                if x>0:
                    count+=len(A)-1
                else:
                    break
            
            now_j=index[0]
            for i in range(len(A)-1,index[1]-1,-1):
                for j in range(now_j,len(A)):
                    if A[i]*A[j]>=x:
                        now_j=j
                        count+=now_j
                        if now_j>=i+1:
                            count-=1
                        break
                else:
                    now_j=len(A)
                    count+=len(A)
                    count-=1

        else:
            now_j=len(A)
            for i in range(index[0]-1,-1,-1):  #A[i]<0
                for j in range(now_j,-1,-1):
                    if A[i]*A[j-1]>=x:
                        now_j=j
                        count+=len(A)-now_j
                        if now_j<=i:
                            count-=1
                        break
            
            now_j=0
            for i in range(index[1],len(A)):
                for j in range(now_j,len(A)):
                    if A[i]*A[j]>=x:
                        now_j=j
                        count+=now_j
                        if now_j>=i+1:
                            count-=1
                        break

        count//=2
        if count<K:
            l=x
        else:
            r=x

    print(l)

if __name__=="__main__":
    main()

Buggy python submission (verdict: Time Limit Exceeded):
import sys
input=sys.stdin.readline
"""
def binary_search_m(i,a,N,A,mid_target):
    left_index=-1
    right_index=N
    while left_index<right_index-1:
        mid_index=(left_index+right_index)//2
        if a*A[mid_index]>=mid_target:
            left_index=mid_index
        else:
            right_index=mid_index
    return N-(left_index+1)

def binary_search_p(i,a,N,A,mid_target):
    left_index=-1
    right_index=N
    while left_index<right_index-1:
        mid_index=(left_index+right_index)//2
        if a*A[mid_index]<mid_target:
            left_index=mid_index
        else:
            right_index=mid_index
    return left_index+1
"""
def main():
    N,K=map(int,input().split())
    A=list(map(int,input().split()))
    A.sort()

    left_target=-10**18
    right_target=10**18+1
    while left_target<right_target-1:
        mid_target=(left_target+right_target)//2
        count=0
        for i in range(N):
            a=A[i]
            if a<0:
                left_index=-1
                right_index=N
                while left_index<right_index-1:
                    mid_index=(left_index+right_index)//2
                    if a*A[mid_index]>=mid_target:
                        left_index=mid_index
                    else:
                        right_index=mid_index
                count+=N-(left_index+1)
            else:
                left_index=-1
                right_index=N
                while left_index<right_index-1:
                    mid_index=(left_index+right_index)//2
                    if a*A[mid_index]<mid_target:
                        left_index=mid_index
                    else:
                        right_index=mid_index
                count+=left_index+1

            if a*a<mid_target:
                count-=1
        count//=2
        if count<K:
            left_target=mid_target
        else:
            right_target=mid_target
    print(left_target)

if __name__=="__main__":
    main()

Fixed submission:
from sys import stdin
def main():
    readline=stdin.readline
    N,K=map(int,readline().split())
    A=list(map(int,readline().split()))
    A.sort()

    #符号が - → 0 , 0 → + となるindexを求める
    index=[len(A),len(A)]
    mode=0
    for i in range(N):
        if mode==0:
            if A[i]==0:
                index[0]=i
                mode=1
            elif A[i]>0:
                index[0],index[1]=i,i
                break
        else:
            if A[i]>0:
                index[1]=i
                break

    #二分探索
    l=-10**18
    r=10**18+1
    while(l<r-1):
        x=(l+r)//2
        count=0

        #尺取り法
        if x>0:
            now_j=index[0]
            for i in range(index[0]):  #A[i]<0
                for j in range(now_j,-1,-1):
                    if A[i]*A[j-1]>=x:
                        now_j=j
                        count+=len(A)-now_j
                        if now_j<=i:
                            count-=1
                        break
                else:
                    now_j=0
                    count+=len(A)
                    count-=1

            for i in range(index[0],index[1]):  #A[i]=0
                if x>0:
                    count+=len(A)-1
                else:
                    break
            
            now_j=index[0]
            for i in range(len(A)-1,index[1]-1,-1):
                for j in range(now_j,len(A)):
                    if A[i]*A[j]>=x:
                        now_j=j
                        count+=now_j
                        if now_j>=i+1:
                            count-=1
                        break
                else:
                    now_j=len(A)
                    count+=len(A)
                    count-=1

        else:
            now_j=len(A)
            for i in range(index[0]-1,-1,-1):  #A[i]<0
                for j in range(now_j,-1,-1):
                    if A[i]*A[j-1]>=x:
                        now_j=j
                        count+=len(A)-now_j
                        if now_j<=i:
                            count-=1
                        break
            
            now_j=0
            for i in range(index[1],len(A)):
                for j in range(now_j,len(A)):
                    if A[i]*A[j]>=x:
                        now_j=j
                        count+=now_j
                        if now_j>=i+1:
                            count-=1
                        break

        count//=2
        if count<K:
            l=x
        else:
            r=x

    print(l)

if __name__=="__main__":
    main()

Buggy python submission (verdict: Time Limit Exceeded):
import sys
input=sys.stdin.readline
def binary_search_m(i,a,N,A,mid_target):
    left_index=-1
    right_index=N
    while left_index<right_index-1:
        mid_index=(left_index+right_index)//2
        if a*A[mid_index]>=mid_target:
            left_index=mid_index
        else:
            right_index=mid_index
    return N-(left_index+1)

def binary_search_p(i,a,N,A,mid_target):
    left_index=-1
    right_index=N
    while left_index<right_index-1:
        mid_index=(left_index+right_index)//2
        if a*A[mid_index]<mid_target:
            left_index=mid_index
        else:
            right_index=mid_index
    return left_index+1

def main():
    N,K=map(int,input().split())
    A=list(map(int,input().split()))
    A.sort()

    left_target=-10**18
    right_target=10**18+1
    while left_target<right_target-1:
        mid_target=(left_target+right_target)//2
        count=0
        for i in range(N):
            a=A[i]
            if a<0:
                count+=binary_search_m(i,a,N,A,mid_target)
            elif a>=0:
                count+=binary_search_p(i,a,N,A,mid_target)

            if a*a<mid_target:
                count-=1
        count//=2
        if count<K:
            left_target=mid_target
        else:
            right_target=mid_target
    print(left_target)

if __name__=="__main__":
    main()

Fixed submission:
from sys import stdin
def main():
    readline=stdin.readline
    N,K=map(int,readline().split())
    A=list(map(int,readline().split()))
    A.sort()

    #符号が - → 0 , 0 → + となるindexを求める
    index=[len(A),len(A)]
    mode=0
    for i in range(N):
        if mode==0:
            if A[i]==0:
                index[0]=i
                mode=1
            elif A[i]>0:
                index[0],index[1]=i,i
                break
        else:
            if A[i]>0:
                index[1]=i
                break

    #二分探索
    l=-10**18
    r=10**18+1
    while(l<r-1):
        x=(l+r)//2
        count=0

        #尺取り法
        if x>0:
            now_j=index[0]
            for i in range(index[0]):  #A[i]<0
                for j in range(now_j,-1,-1):
                    if A[i]*A[j-1]>=x:
                        now_j=j
                        count+=len(A)-now_j
                        if now_j<=i:
                            count-=1
                        break
                else:
                    now_j=0
                    count+=len(A)
                    count-=1

            for i in range(index[0],index[1]):  #A[i]=0
                if x>0:
                    count+=len(A)-1
                else:
                    break
            
            now_j=index[0]
            for i in range(len(A)-1,index[1]-1,-1):
                for j in range(now_j,len(A)):
                    if A[i]*A[j]>=x:
                        now_j=j
                        count+=now_j
                        if now_j>=i+1:
                            count-=1
                        break
                else:
                    now_j=len(A)
                    count+=len(A)
                    count-=1

        else:
            now_j=len(A)
            for i in range(index[0]-1,-1,-1):  #A[i]<0
                for j in range(now_j,-1,-1):
                    if A[i]*A[j-1]>=x:
                        now_j=j
                        count+=len(A)-now_j
                        if now_j<=i:
                            count-=1
                        break
            
            now_j=0
            for i in range(index[1],len(A)):
                for j in range(now_j,len(A)):
                    if A[i]*A[j]>=x:
                        now_j=j
                        count+=now_j
                        if now_j>=i+1:
                            count-=1
                        break

        count//=2
        if count<K:
            l=x
        else:
            r=x

    print(l)

if __name__=="__main__":
    main()

Buggy python submission (verdict: Time Limit Exceeded):
import sys
input=sys.stdin.readline
def binary_search_m(i,a,N,A,mid_target):
    left_index=-1
    right_index=N
    while left_index<right_index-1:
        mid_index=(left_index+right_index)//2
        if a*A[mid_index]>=mid_target:
            left_index=mid_index
        else:
            right_index=mid_index
    return N-(left_index+1)

def binary_search_p(i,a,N,A,mid_target):
    left_index=-1
    right_index=N
    while left_index<right_index-1:
        mid_index=(left_index+right_index)//2
        if a*A[mid_index]<mid_target:
            left_index=mid_index
        else:
            right_index=mid_index
    return left_index+1

def main():
    N,K=map(int,input().split())
    A=list(map(int,input().split()))
    A.sort()

    left_target=-10**18
    right_target=10**18+1
    while left_target<right_target-1:
        mid_target=(left_target+right_target)//2
        count=0
        for i in range(N):
            a=A[i]
            if a<0:
                count+=binary_search_m(i,a,N,A,mid_target)
            elif a>=0:
                count+=binary_search_p(i,a,N,A,mid_target)

            if a*a<mid_target:
                count-=1
        count//=2
        if count<K:
            left_target=mid_target
        else:
            right_target=mid_target
    print(left_target)

if __name__=="__main__":
    main()

Fixed submission:
from sys import stdin
def main():
    readline=stdin.readline
    N,K=map(int,readline().split())
    A=list(map(int,readline().split()))
    A.sort()

    #符号が - → 0 , 0 → + となるindexを求める
    index=[len(A),len(A)]
    mode=0
    for i in range(N):
        if mode==0:
            if A[i]==0:
                index[0]=i
                mode=1
            elif A[i]>0:
                index[0],index[1]=i,i
                break
        else:
            if A[i]>0:
                index[1]=i
                break

    #二分探索
    l=-10**18
    r=10**18+1
    while(l<r-1):
        x=(l+r)//2
        count=0

        #尺取り法
        if x>0:
            now_j=index[0]
            for i in range(index[0]):  #A[i]<0
                for j in range(now_j,-1,-1):
                    if A[i]*A[j-1]>=x:
                        now_j=j
                        count+=len(A)-now_j
                        if now_j<=i:
                            count-=1
                        break
                else:
                    now_j=0
                    count+=len(A)
                    count-=1

            for i in range(index[0],index[1]):  #A[i]=0
                if x>0:
                    count+=len(A)-1
                else:
                    break
            
            now_j=index[0]
            for i in range(len(A)-1,index[1]-1,-1):
                for j in range(now_j,len(A)):
                    if A[i]*A[j]>=x:
                        now_j=j
                        count+=now_j
                        if now_j>=i+1:
                            count-=1
                        break
                else:
                    now_j=len(A)
                    count+=len(A)
                    count-=1

        else:
            now_j=len(A)
            for i in range(index[0]-1,-1,-1):  #A[i]<0
                for j in range(now_j,-1,-1):
                    if A[i]*A[j-1]>=x:
                        now_j=j
                        count+=len(A)-now_j
                        if now_j<=i:
                            count-=1
                        break
            
            now_j=0
            for i in range(index[1],len(A)):
                for j in range(now_j,len(A)):
                    if A[i]*A[j]>=x:
                        now_j=j
                        count+=now_j
                        if now_j>=i+1:
                            count-=1
                        break

        count//=2
        if count<K:
            l=x
        else:
            r=x

    print(l)

if __name__=="__main__":
    main()

Buggy python submission (verdict: Time Limit Exceeded):
import sys
input=sys.stdin.readline
import bisect
def binary_search_m(i,a,A,mid_target):
    left_index=-1
    right_index=len(A)
    if len(A)==1:
        if a*A[i]>=mid_target:
            return 0
        else:
            return 1
    else:
        while left_index<right_index-1:
            mid_index=(left_index+right_index)//2
            if a*A[mid_index]>=mid_target:
                left_index=mid_index
            else:
                right_index=mid_index
        return len(A)-(left_index+1)

def binary_search_p(i,a,A,mid_target):
    left_index=-1
    right_index=len(A)
    if len(A)==1:
        if a*A[0]<mid_target:
            return 1
        else:
            return 0
    else:
        while left_index<right_index-1:
            mid_index=(left_index+right_index)//2
            if a*A[mid_index]<mid_target:
                left_index=mid_index
            else:
                right_index=mid_index
        return left_index+1

def main():
    N,K=map(int,input().split())
    A=list(map(int,input().split()))
    A.sort()

    left_target=-10**18
    right_target=10**18+1
    while left_target<right_target-1:
        mid_target=(left_target+right_target)//2
        #print(mid_target)
        count=0
        for i in range(N-1):
            a=A[i]
            if a<0:
                count+=binary_search_m(i,a,A[i+1:],mid_target)
            elif a==0:
                if mid_target>0:
                    count+=(N-(i+1))
            elif a>0:
                count+=binary_search_p(i,a,A[i+1:],mid_target)
            #print("a:",a,"c",count)
        if count<K:
            left_target=mid_target
        else:
            right_target=mid_target
        #print(count)
    print(left_target)

if __name__=="__main__":
    main()

Fixed submission:
from sys import stdin
def main():
    readline=stdin.readline
    N,K=map(int,readline().split())
    A=list(map(int,readline().split()))
    A.sort()

    #符号が - → 0 , 0 → + となるindexを求める
    index=[len(A),len(A)]
    mode=0
    for i in range(N):
        if mode==0:
            if A[i]==0:
                index[0]=i
                mode=1
            elif A[i]>0:
                index[0],index[1]=i,i
                break
        else:
            if A[i]>0:
                index[1]=i
                break

    #二分探索
    l=-10**18
    r=10**18+1
    while(l<r-1):
        x=(l+r)//2
        count=0

        #尺取り法
        if x>0:
            now_j=index[0]
            for i in range(index[0]):  #A[i]<0
                for j in range(now_j,-1,-1):
                    if A[i]*A[j-1]>=x:
                        now_j=j
                        count+=len(A)-now_j
                        if now_j<=i:
                            count-=1
                        break
                else:
                    now_j=0
                    count+=len(A)
                    count-=1

            for i in range(index[0],index[1]):  #A[i]=0
                if x>0:
                    count+=len(A)-1
                else:
                    break
            
            now_j=index[0]
            for i in range(len(A)-1,index[1]-1,-1):
                for j in range(now_j,len(A)):
                    if A[i]*A[j]>=x:
                        now_j=j
                        count+=now_j
                        if now_j>=i+1:
                            count-=1
                        break
                else:
                    now_j=len(A)
                    count+=len(A)
                    count-=1

        else:
            now_j=len(A)
            for i in range(index[0]-1,-1,-1):  #A[i]<0
                for j in range(now_j,-1,-1):
                    if A[i]*A[j-1]>=x:
                        now_j=j
                        count+=len(A)-now_j
                        if now_j<=i:
                            count-=1
                        break
            
            now_j=0
            for i in range(index[1],len(A)):
                for j in range(now_j,len(A)):
                    if A[i]*A[j]>=x:
                        now_j=j
                        count+=now_j
                        if now_j>=i+1:
                            count-=1
                        break

        count//=2
        if count<K:
            l=x
        else:
            r=x

    print(l)

if __name__=="__main__":
    main()