Buggy python submission (verdict: Time Limit Exceeded):
from heapq import heapify, heappop, heappush


N, M, V, P = map(int, input().split())
A = list(map(int, input().split()))
A.sort(reverse=True)


def isPossible(i):
    i = A.index(A[i])
    if i < P:
        return True
    numVotes = V
    score = A[i] + M
    numVotes -= 1
    if A[P - 1] > score:
        return False
    numVotes -= P - 1
    numVotes -= N - i - 1
    if numVotes:
        heap = A[P - 1 : i][::-1]
        for j in range(M):
            temp = []
            for k in range(numVotes):
                temp.append(heappop(heap))
            for x in temp:
                heappush(heap, x + 1)
        return max(heap) <= score
    return True


if not isPossible(0):
    print(0)
elif isPossible(N - 1):
    print(N)
else:
    lo = 0
    hi = N - 1
    assert isPossible(lo)
    assert not isPossible(hi)
    while hi - lo > 1:
        mid = (lo + hi) // 2
        if isPossible(mid):
            lo = mid
        else:
            hi = mid
    assert isPossible(lo)
    assert not isPossible(lo + 1)
    print(lo + 1)


Fixed submission:
N, M, V, P = map(int, input().split())
A = list(map(int, input().split()))
A.sort(reverse=True)


def isPossible(i):
    # Get highest rank with the same score
    i = A.index(A[i])

    # If already high rank, can vote top V to keep relative ordering
    if i < P:
        return True

    numVotes = V
    # Otherwise have every judge vote for i-th first
    # Each judge has V - 1 votes remaining
    score = A[i] + M
    numVotes -= 1
    # This is the best possible rank (more voting can only decrease rank)
    # If it isn't good enough, return early
    if A[P - 1] > score:
        return False
    # Soak up votes by voting for everything after i-th
    # Since adding M to everything, they will still be smaller
    numVotes -= N - i - 1
    # Soak up more votes by voting for everything in the top P - 1
    # Our element just needs to be within top P even if it's last
    numVotes -= P - 1
    if numVotes > 0:
        # If there are any votes remaining, it will be for indices P-1 thru i-1
        # We currently have:
        # A[i] + M >= A[P-1] >= A[P-2] >= ... >= A[i - 1] > A[i]
        # We want to distribute the remaining votes so that none of these become
        # greater than A[i] + M
        remainingVotes = numVotes * M
        gap = sum(score - x for x in A[P - 1 : i])
        return gap >= remainingVotes
    return True


if not isPossible(0):
    print(0)
elif isPossible(N - 1):
    print(N)
else:
    # If i-th is possible, so is 0th to (i-1)th
    # So binary search for the last index possible
    lo = 0
    hi = N - 1
    assert isPossible(lo)
    assert not isPossible(hi)
    while hi - lo > 1:
        mid = (lo + hi) // 2
        if isPossible(mid):
            lo = mid
        else:
            hi = mid
    assert isPossible(lo)
    assert not isPossible(lo + 1)
    # If index i is possible, there are i+1 possible problems
    print(lo + 1)

Buggy python submission (verdict: Time Limit Exceeded):
from heapq import heapify, heappop, heappush


N, M, V, P = map(int, input().split())
A = list(map(int, input().split()))
A.sort(reverse=True)


def isPossible(i):
    a = list(A)
    i = a.index(a[i])
    if i < P:
        return True
    numVotes = V
    a[i] += M
    score = a[i]
    numVotes -= 1
    if a[P - 1] > score:
        return False
    for j in range(N):
        if numVotes:
            if j < P - 1 or j > i:
                a[j] += M
                numVotes -= 1
        else:
            break
    if numVotes:
        heap = a[P - 1 : i]
        heapify(heap)
        for j in range(M):
            temp = []
            for k in range(numVotes):
                temp.append(heappop(heap))
            for x in temp:
                heappush(heap, x + 1)
        return max(heap) <= score
    return True


if not isPossible(0):
    print(0)
elif isPossible(N - 1):
    print(N)
else:
    lo = 0
    hi = N - 1
    assert isPossible(lo)
    assert not isPossible(hi)
    while hi - lo > 1:
        mid = (lo + hi) // 2
        if isPossible(mid):
            lo = mid
        else:
            hi = mid
    assert isPossible(lo)
    assert not isPossible(lo + 1)
    print(lo + 1)


Fixed submission:
N, M, V, P = map(int, input().split())
A = list(map(int, input().split()))
A.sort(reverse=True)


def isPossible(i):
    # Get highest rank with the same score
    i = A.index(A[i])

    # If already high rank, can vote top V to keep relative ordering
    if i < P:
        return True

    numVotes = V
    # Otherwise have every judge vote for i-th first
    # Each judge has V - 1 votes remaining
    score = A[i] + M
    numVotes -= 1
    # This is the best possible rank (more voting can only decrease rank)
    # If it isn't good enough, return early
    if A[P - 1] > score:
        return False
    # Soak up votes by voting for everything after i-th
    # Since adding M to everything, they will still be smaller
    numVotes -= N - i - 1
    # Soak up more votes by voting for everything in the top P - 1
    # Our element just needs to be within top P even if it's last
    numVotes -= P - 1
    if numVotes > 0:
        # If there are any votes remaining, it will be for indices P-1 thru i-1
        # We currently have:
        # A[i] + M >= A[P-1] >= A[P-2] >= ... >= A[i - 1] > A[i]
        # We want to distribute the remaining votes so that none of these become
        # greater than A[i] + M
        remainingVotes = numVotes * M
        gap = sum(score - x for x in A[P - 1 : i])
        return gap >= remainingVotes
    return True


if not isPossible(0):
    print(0)
elif isPossible(N - 1):
    print(N)
else:
    # If i-th is possible, so is 0th to (i-1)th
    # So binary search for the last index possible
    lo = 0
    hi = N - 1
    assert isPossible(lo)
    assert not isPossible(hi)
    while hi - lo > 1:
        mid = (lo + hi) // 2
        if isPossible(mid):
            lo = mid
        else:
            hi = mid
    assert isPossible(lo)
    assert not isPossible(lo + 1)
    # If index i is possible, there are i+1 possible problems
    print(lo + 1)