Buggy python submission (verdict: Time Limit Exceeded):
def main():
    N, M, V, P = (int(i) for i in input().split())
    A = [int(i) for i in input().split()]
    A.sort(reverse=True)
    not_ans = 0
    for i in range(P, N):
        if A[i] + M < A[P-1]:
            not_ans += 1
            continue
        votable = M + (P-1) * M + (N - i - 1)*M
        for j in range(P-1, i):
            votable += max(0, A[i] + M - A[j])
        if votable < M*V:
            not_ans += 1

    print(N - not_ans)


if __name__ == '__main__':
    main()


Fixed submission:
def main():
    N, M, V, P = (int(i) for i in input().split())
    A = [int(i) for i in input().split()]
    A.sort(reverse=True)

    def is_ok(mid):
        if mid <= P-1:
            return False  # 採用可能
        if A[mid] + M < A[P-1]:
            return True  # 採用不可能
        votable = M + (P-1) * M + (N - (mid + 1))*M
        for i in range(P-1, mid):
            votable += min(M, max(0, A[mid] + M - A[i]))
        if M*V <= votable:
            return False
        else:
            return True

    def binary_search_meguru():
        left = -1
        right = N
        while right - left > 1:
            mid = left + ((right - left) // 2)
            if is_ok(mid):
                right = mid
            else:
                left = mid
        return right
    print(binary_search_meguru())


if __name__ == '__main__':
    main()

Buggy python submission (verdict: Runtime Error):
def main():
    N, M, V, P = (int(i) for i in input().split())
    A = [int(i) for i in input().split()]
    A.sort(reverse=True)

    def is_ok1(mid, val):
        if val >= A[mid]:
            return True
        else:
            return False

    def is_ok2(mid, val):
        if val > A[mid]:
            return True
        else:
            return False

    def binary_search_meguru(val, is_ok):
        left = -1
        right = N
        while right - left > 1:
            mid = left + ((right - left) // 2)
            if is_ok(mid, val):
                right = mid
            else:
                left = mid
        return left

    not_ans = 0
    for i in range(N):
        top = A[i] + M
        upper = binary_search_meguru(top, is_ok1) + 1
        skip = 0
        if (-(V-1)) % N <= i+1:
            skip = 1
        if P <= upper:
            not_ans += 1
        elif A[-(V-1) + (P-1) - upper - skip] + M > top:
            top_less = P - 1
            top_less += max(0, N - binary_search_meguru(top, is_ok2) - 1)
            key = (V-1) - top_less
            mo = M % ((i-1)-(P-1))
            if i - mo <= key and top >= A[(P-1) + key] + M//((i-1)-(P-1) + 1) + 1:
                continue
            elif i - mo > key and top >= A[(P-1) + key] + M//((i-1)-(P-1) + 1):
                continue
            else:
                not_ans += 1

    print(N - not_ans)


if __name__ == '__main__':
    main()


Fixed submission:
def main():
    N, M, V, P = (int(i) for i in input().split())
    A = [int(i) for i in input().split()]
    A.sort(reverse=True)

    def is_ok(mid):
        if mid <= P-1:
            return False  # 採用可能
        if A[mid] + M < A[P-1]:
            return True  # 採用不可能
        votable = M + (P-1) * M + (N - (mid + 1))*M
        for i in range(P-1, mid):
            votable += min(M, max(0, A[mid] + M - A[i]))
        if M*V <= votable:
            return False
        else:
            return True

    def binary_search_meguru():
        left = -1
        right = N
        while right - left > 1:
            mid = left + ((right - left) // 2)
            if is_ok(mid):
                right = mid
            else:
                left = mid
        return right
    print(binary_search_meguru())


if __name__ == '__main__':
    main()