CodeEff/ECCO huggingface dataset:
# Original solution
import math

def func(h, a, b, count):
  ans = 0
  for v in h:
    if v > b * count:
      ans += math.ceil((v-b*count) / (a-b))
      
  return ans <= count

n,a,b = list(map(int, input().split()))
h = []

for i in range(n):
  # heapqを最大値を取り出すように使いたいのでマイナスにする
  h.append(int(eval(input())))

delta = a-b
start = 1
end = math.ceil(max(h) / b)
middle = (end + start) // 2

# 二分探索する、終了条件はぶっちゃけわからん
while True:
  if(func(h,a,b,middle)):
    end = middle
  else:
    start = middle
    
  middle = (end + start) // 2
  if (end - start) == 1:
    break
    
print(end)

# Optimized solution
import math

def func(h, a, b, count):
  ans = 0
  for v in h:
    if v > b * count:
      ans += math.ceil((v-b*count) / (a-b))
      
  return ans <= count

n,a,b = list(map(int, input().split()))
h = []

for i in range(n):
  # heapqを最大値を取り出すように使いたいのでマイナスにする
  h.append(int(eval(input())))

start = 1
end = math.ceil(max(h) / b)
middle = (end + start) // 2

# 二分探索する、終了条件はぶっちゃけわからん
for i in range(1000):
  if(func(h,a,b,middle)):
    end = middle
  else:
    start = middle
    
  middle = (end + start) // 2
  if (end - start) == 1:
    break
    
print(end)
# Original solution
N,A,B = list(map(int,input().split()))
H = [int(eval(input())) for _ in range(N)]

d = A-B

def judge(k):
    cnt = 0
    remain = [max(h-k*B,0) for h in H]
    for r in remain:
        cnt += -(-r // d)
    if cnt <= k:
        return True
    else:
        return False

def biserch(ok,ng,judge):
    while abs(ok-ng) > 1:
        mid = (ok+ng) // 2
        if judge(mid):
            ok = mid
        else:
            ng = mid
    return ok

ans = biserch(10**9,-1,judge)
print(ans)

# Optimized solution
import sys
input = sys.stdin.readline

N,A,B = list(map(int,input().split()))
H = [int(eval(input())) for _ in range(N)]

def judge(k):
    cnt = 0
    for h in H:
        cnt += -(-(max(h-k*B,0))//(A-B))
    if cnt <= k:
        return True
    return False

def biserch(ok,ng,judge):
    while abs(ok-ng) > 1:
        mid = (ok+ng) // 2
        if judge(mid):
            ok = mid
        else:
            ng = mid
    return ok

ans = biserch(max(H),-1,judge)
print(ans)
# Original solution
drops = {
    1: ((0,0,0,0,0), (0,0,1,0,0), (0,1,1,1,0), (0,0,1,0,0), (0,0,0,0,0)),
    2: ((0,0,0,0,0), (0,1,1,1,0), (0,1,1,1,0), (0,1,1,1,0), (0,0,0,0,0)),
    3: ((0,0,1,0,0), (0,1,1,1,0), (1,1,1,1,1), (0,1,1,1,0), (0,0,1,0,0))}

paper = [[0 for i in range(14)] for j in range(14)]

def solve(x, y, size):
    for i in range(5):
        for j in range(5):
            if drops[size][i][j] == 1:
                paper[y+i][x+j] += 1

while True:
    try:
        line = input()
    except EOFError:
        break
    x, y, size = list(map(int, line.split(',')))
    solve(x, y, size)

s = c = 0
for i in range(2, 12):
    for j in range(2, 12):
        if paper[i][j] == 0:
            c += 1
        if s < paper[i][j]:
            s = paper[i][j]

print(c)
print(s)

# Optimized solution
drops = {
    1: ((0,0,0,0,0), (0,0,1,0,0), (0,1,1,1,0), (0,0,1,0,0), (0,0,0,0,0)),
    2: ((0,0,0,0,0), (0,1,1,1,0), (0,1,1,1,0), (0,1,1,1,0), (0,0,0,0,0)),
    3: ((0,0,1,0,0), (0,1,1,1,0), (1,1,1,1,1), (0,1,1,1,0), (0,0,1,0,0))}

paper = [[0] * 14 for j in range(14)]

def solve(x, y, size):
    for i in range(5):
        for j in range(5):
            if drops[size][i][j] == 1:
                paper[y+i][x+j] += 1

while True:
    try:
        line = input()
    except EOFError:
        break
    solve(*list(map(int, line.split(','))))

result = [f for i in [l[2:12] for l in paper[2:12]] for f in i]

print(result.count(0))
print(max(result))
# Original solution
N,M,V,P = list(map(int,input().split()))
A = sorted(list(map(int,input().split())),reverse= True)

def check(i):
  if i <= P-1:
    return True
  vote = (V-1)*M
  vote -= (N-1-i)*M
  vote -= (P-1)*M
  if vote <= 0:
    return A[i]+M >= A[P-1]
  else:
    for j in range(i-1,P-1,-1):
      if A[j] > A[i]+M:
        return False
      v = min(A[i]+M-A[j],M,vote)
      vote -= v
      if vote <= 0:
        break
    if vote <= 0:
      return A[i]+M >= A[P-1]
    else:
      return A[i]+M >= A[P-1]+vote

ok = -1
ng = N
while(ok+1 < ng):
  md = (ok+ng)//2
  if check(md):
    ok = md
  else:
    ng = md
print((ok+1))

# Optimized solution
N,M,V,P = list(map(int,input().split()))
A = sorted(list(map(int,input().split())),reverse= True)

def check(i):
  if i <= P-1:
    return True
  vote = (V-1)*M
  vote -= (N-1-i)*M
  vote -= (P-1)*M
  if vote <= 0:
    return A[i]+M >= A[P-1]
  else:
    for j in range(i-1,P-1,-1):
      if A[j] > A[i]+M:
        return False
      vote -= min(A[i]+M-A[j],M)
      if vote <= 0:
        break
    if vote <= 0:
      return A[i]+M >= A[P-1]
    else:
      return A[i]+M >= A[P-1]+vote

ok = -1
ng = N
while(ok+1 < ng):
  md = (ok+ng)//2
  if check(md):
    ok = md
  else:
    ng = md
print((ok+1))
# Original solution
import sys
input = sys.stdin.readline

def judge(x):
    if N-P<=x<=N-1:
        return True
    if A[x]+M<A[N-P]:
        return False
    
    cnt = 0
    
    for i in range(N):
        if i>=N-P+1:
            cnt += M
        else:
            cnt += min(M, A[x]+M-A[i])
    
    return cnt>=M*V

def binary_search():
    l, r = 0, N-1
    
    while l<=r:
        m = (l+r)//2
        
        if judge(m):
            r = m-1
        else:
            l = m+1
    
    return l

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

print((N-binary_search()))

# Optimized solution
import sys
input = sys.stdin.readline

def judge(x):
    if N-P<=x<=N-1:
        return True
    if A[x]+M<A[N-P]:
        return False
    
    cnt = 0
    
    for i in range(N-P+1):
        if i==x:
            continue
        
        cnt += min(M, A[x]+M-A[i])
    
    return cnt>=M*(V-P)

def binary_search():
    l, r = 0, N-1
    
    while l<=r:
        m = (l+r)//2
        
        if judge(m):
            r = m-1
        else:
            l = m+1
    
    return l

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

print((N-binary_search()))
# Original solution
def judge(a, i, m, n, v, p):
    if i <= p: return True
    if a[i-1] + m < a[p-1]: return False
    check = (p + n - i)*m
    for j in range(p, i):
        check += a[i-1] + m - a[j-1]
    return check >= m*v

n, m, v, p = list(map(int, input().split()))
a = list(map(int, input().split()))

a.sort(reverse=True)
ng = n + 1
ok = 0

while (ng - ok) > 1:
    mid = (ok + ng) // 2
    if judge(a, mid, m, n, v, p):
        ok = mid
    else:
        ng = mid
print(ok)

# Optimized solution
def judge(a, acc, i, m, n, v, p):
    if i <= p: return True
    if a[i-1] + m < a[p-1]: return False
    check = (p + n - i)*m + (a[i-1] + m)*(i - p) - (acc[i-2] - acc[p-2])
    return check >= m*v

n, m, v, p = list(map(int, input().split()))
a = list(map(int, input().split()))

a.sort(reverse=True)
acc = [0] * (n+1)
for i in range(n):
    acc[i] = a[0] if i == 0 else a[i] + acc[i-1]
ng = n + 1
ok = 0

while (ng - ok) > 1:
    mid = (ok + ng) // 2
    if judge(a, acc, mid, m, n, v, p):
        ok = mid
    else:
        ng = mid
print(ok)
# Original solution
# coding: utf-8


def solve(*args: str) -> str:
    n, m, v, p = list(map(int, args[0].split()))
    A = list(map(int, args[1].split()))
    A.sort()

    ret = 0
    for i in range(n):
        if A[i]+m < A[n-p]:
            continue
        pts = m*min(n, i+p)
        for j in range(i+1, n-(p-1)):
            pts += max(0, A[i]+m-A[j])

        if m*v <= pts:
            ret = n-i
            break

    return str(ret)


if __name__ == "__main__":
    print((solve(*(open(0).read().splitlines()))))


# Optimized solution
# coding: utf-8


def solve(*args: str) -> str:
    n, m, v, p = list(map(int, args[0].split()))
    A = list(map(int, args[1].split()))
    A.sort()

    left, right = -1, n

    while left+1 < right:
        i = (left+right)//2

        if A[i]+m < A[n-p]:
            left = i
            continue

        pts = m*min(n, i+p)
        for j in range(i+1, n-(p-1)):
            pts += max(0, A[i]+m-A[j])

        if m*v <= pts:
            right = i
        else:
            left = i

    return str(n-right)


if __name__ == "__main__":
    print((solve(*(open(0).read().splitlines()))))
# Original solution
from heapq import heapify, heappop, heappush


N, M, V, P = list(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))


# Optimized solution
N, M, V, P = list(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))
# Original solution
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()


# Optimized solution
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()
# Original solution
n,m,v,p=[int(j) for j in input().split()]
a=[int(j) for j in input().split()]
a.sort(reverse=True)

def f(x):
    if x>n-1:
        return False
    if x<p:
        return True
    if a[x]+m<a[p-1]:
        return False
    tmp=m*(p+n-x-1)
    for i in range(p-1,x):
        tmp+=min(m,a[x]+m-a[i])
    if tmp>=m*v:
        return True
    return False
left=-1
right=n
while right-left>1:
    mid=(left+right)//2
    if f(mid):
        left=mid
    else:
        right=mid
print((left+1))

# Optimized solution
n,m,v,p=[int(j) for j in input().split()]
a=[int(j) for j in input().split()]
a.sort(reverse=True)

def f(x):
    if x>n-1:
        return False
    if x<p:
        return True
    if a[x]+m<a[p-1]:
        return False
    tmp=m*(p+n-x-1)
    for i in range(p-1,x):
        tmp+=a[x]+m-a[i]
    if tmp>=m*v:
        return True
    return False

left=0
right=n
while right-left>1:
    mid=(left+right)//2
    if f(mid):
        left=mid
    else:
        right=mid
print((left+1))
# Original solution
import sys
from bisect import bisect_right, bisect_left
input = sys.stdin.readline
n, m, v, p = [int(x) for x in input().strip().split()]
araw = sorted([int(x) for x in input().strip().split()])
a = list(reversed(araw))

def f(x, n, m, v, p, a, araw):
    c = p - (n - bisect_right(araw, a[x-1]+m)) - 1
    if c < 0:
        return False
    vote = m * (v - 1)
    a[x-1] += m
    thr = a[x-1]
    for i, aa in enumerate(a, start=1):
        if vote <= 0:
            break
        if i == x:
            continue
        if aa > thr:
            a[i-1] += m
            vote -= m
        elif aa == thr:
            if c:
                a[i-1] += m
                vote -= m
                c -= 1
        elif thr - aa < m:
            if c:
                a[i-1] += m
                vote -= m
                c -= 1
            else:
                v_ = min(vote, thr - aa, m)
                a[i-1] += v_
                vote -= v_
        else:
            a[i-1] += m
            vote -= m
    return vote <= 0

x = 0
l = 1
r = n + 1
while l < r:
    x = (l + r) // 2
    if f(x, n, m, v, p, a[:], araw):
        l = x + 1
    else:
        r = x
print((l-1))

# Optimized solution
import sys
from bisect import bisect_right, bisect_left
input = sys.stdin.readline
n, m, v, p = [int(x) for x in input().strip().split()]
araw = sorted([int(x) for x in input().strip().split()])
a = list(reversed(araw))

def f(x, n, m, v, p, a, araw):
    c = p - (n - bisect_right(araw, a[x-1]+m)) - 1
    if c < 0:
        return False
    vote = m * (v - 1)
    thr = a[x-1] + m
    for i, aa in enumerate(a, start=1):
        if vote <= 0:
            break
        if i == x:
            continue
        if aa > thr:
            vote -= m
        elif aa == thr:
            if c:
                vote -= m
                c -= 1
        elif thr - aa < m:
            if c:
                vote -= m
                c -= 1
            else:
                v_ = min(vote, thr - aa, m)
                vote -= v_
        else:
            vote -= m
    return vote <= 0

x = 0
l = 1
r = n + 1
while l < r:
    x = (l + r) // 2
    if f(x, n, m, v, p, a[:], araw):
        l = x + 1
    else:
        r = x
print((l-1))
# Original solution
import sys

read = sys.stdin.buffer.read
input = sys.stdin.buffer.readline
inputs = sys.stdin.buffer.readlines


# mod=10**9+7
# rstrip().decode('utf-8')
# map(int,input().split())
#import numpy as np
import bisect



def main():
	n,m,v,p=list(map(int,input().split()))
	A=list(map(int,input().split()))
	A.sort(reverse=True)
	teki=A[p-1]
	
	ans=0
	cnt=1
	d=0
	
	for i in range(p,n):
		if A[i]+m<teki:break
		d+=cnt*(A[i-1]-A[i])
		if d>m*(n-v):break
		cnt+=1
		ans+=1
	print((p+ans))
	
if __name__ == "__main__":
	main()


# Optimized solution
import sys

read = sys.stdin.buffer.read
input = sys.stdin.buffer.readline
inputs = sys.stdin.buffer.readlines


# mod=10**9+7
# rstrip().decode('utf-8')
# map(int,input().split())
#import numpy as np

def main():
	n,m,v,p=list(map(int,input().split()))
	A=list(map(int,input().split()))
	A.sort(reverse=True)
	teki=A[p-1]
	
	cnt=1
	d=0
	
	for i in range(p,n):
		if A[i]+m<teki:break
		d+=cnt*(A[i-1]-A[i])
		if d>m*(n-v):break
		cnt+=1
	print((p+cnt+-1))
	
	
	
if __name__ == "__main__":
	main()
# Original solution
def check(n):

    if n <= P-1:
        return True

    if A[n]+M < A[P-1]:
        return False
    
    votes = (P+N-1-n)*M + sum([A[n]+M-A[i] for i in range(P-1,n)])

    if votes < M*V:
        return False
    else:
        return True

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

A.sort(reverse=True)

##開区間
right = N
left = 0

while abs(right-left) > 1:

    mid = (right+left)//2

    if check(mid):
        left = mid
    else:
        right = mid

print((left+1))

# Optimized solution
def check(n):

    if n <= P-1:
        return True

    if A[n]+M < A[P-1]:
        return False
    
    votes = (P+N-1-n)*M + sum([A[n]+M-i for i in A[P-1:n]])

    if votes < M*V:
        return False
    else:
        return True

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

A.sort(reverse=True)

##開区間
right = N
left = 0

while abs(right-left) > 1:

    mid = (right+left)//2

    if check(mid):
        left = mid
    else:
        right = mid

print((left+1))
# Original solution
import math
N, M, V, P = list(map(int, input().split()))
A_ = list(map(int, input().split()))
A = sorted(A_)
temp = 0
for i in range(N):
  points = V - P - i
  if points < 0:
    points = 0
  requires = 0
  for j in range(i+1, N-P):
    requires += A[N-P] - A[j]
  kabe = N - P - i
  if kabe == 0:
    temp = i
    break
  else:
    wall = points * M - requires
    if wall < 0:
      wall = 0
    wall_2 = math.ceil(wall / kabe)
    wall_3 = A[N-P] + wall_2
    i_points = A[i] + M
    if i_points >= wall_3:
      temp = i
      break
print((N - temp))

# Optimized solution
import math
N, M, V, P = list(map(int, input().split()))
A_ = list(map(int, input().split()))
A = sorted(A_)
temp = 0
requires = 0
for i in range(N-P):
  requires += A[N-P] - A[i]
for i in range(N):
  points = V - P - i
  if points < 0:
    points = 0
  requires -= A[N-P] - A[i]
  kabe = N - P - i
  if kabe == 0:
    temp = i
    break
  else:
    wall = points * M - requires
    if wall < 0:
      wall = 0
    wall_2 = math.ceil(wall / kabe)
    wall_3 = A[N-P] + wall_2
    i_points = A[i] + M
    if i_points >= wall_3:
      temp = i
      break
print((N - temp))
# Original solution
import sys
from math import factorial
from fractions import Fraction
import heapq, bisect, fractions
import math
import itertools
sys.setrecursionlimit(10 ** 5 + 10)
INF = 10**15 +5
def input(): return sys.stdin.readline().strip()
def INT(): return int(eval(input()))
def MAP(): return list(map(int, input().split()))
def LIST(): return list(map(int, input().split()))
MOD = 10**9 + 7

n, m, v, p = MAP()
a = LIST()
a = sorted(a, reverse=True)

def hantei(i):
    if i < p: return True
    if a[p-1] > a[i] + m: return False
    if ((i-p+1)*(a[i]+m)-sum(a[p-1:i]))+m*(p-1+n-i) < m*v: return False
    return True

def check(x):
    if (n-x)<=p:
        return True
 
    x_score = a[x]+m
    total_v = (v-x-p)*m
 
    if(a[n-p]>x_score):
        return False
 
    for i in range(x+1,n-p+1):
        total_v -= min(m,(x_score -a[i]))
    if total_v <= 0:
        return True
    else:
        return False

if hantei(n-1):
    print(n)
    sys.exit()
right = n-1
left = 0

while right-left > 1:
    mid = (right+left)//2
    if hantei(mid):
        left = mid
    else:
        right = mid

print(right)

# Optimized solution
import sys
from math import factorial
from fractions import Fraction
import heapq, bisect, fractions
import math
import itertools
sys.setrecursionlimit(10 ** 5 + 10)
INF = 10**15 +5
def input(): return sys.stdin.readline().strip()
def INT(): return int(eval(input()))
def MAP(): return list(map(int, input().split()))
def LIST(): return list(map(int, input().split()))
MOD = 10**9 + 7

n, m, v, p = MAP()
a = LIST()
a = sorted(a, reverse=True)

def hantei(i):
    if i < p: return True
    if a[p-1] > a[i] + m: return False
    if ((i-p+1)*(a[i]+m)-sum(a[p-1:i]))+m*(p-1+n-i) < m*v: return False
    return True

if hantei(n-1):
    print(n)
    sys.exit()
    
right = n-1
left = 0

while right-left > 1:
    mid = (right+left)//2
    if hantei(mid):
        left = mid
    else:
        right = mid

print(right)
# Original solution
#!usr/bin/env python3
from collections import defaultdict,deque
from heapq import heappush, heappop
from itertools import permutations
import sys
import math
import bisect
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def I(): return int(sys.stdin.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():
    n,m,v,p = LI()
    a = LI()
    a.sort()
    l = -1
    r = n-1
    while r-l > 1:
        i = (l+r) >> 1
        ai = a[i]
        aim = ai+m
        ri = bisect.bisect_right(a,aim)
        if n-ri >= p:
            l = i
            continue
        cnt = 0
        for j in range(n-p+1):
            if i == j:
                continue
            cnt += min(m,aim-a[j])
        if cnt >= m*(v-p):
            r = i
        else:
            l = i
    print((n-r))
    return

#Solve
if __name__ == "__main__":
    solve()


# Optimized solution
#!usr/bin/env python3
from collections import defaultdict, deque
from heapq import heappush, heappop
from itertools import permutations, accumulate
import sys
import math
import bisect
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def I(): return int(sys.stdin.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():
    n,m,v,p = LI()
    a = LI()
    a.sort()
    l = -1
    r = n-1
    while l+1 < r:
        i = (l+r) >> 1
        A = a[i]+m
        ri = bisect.bisect_right(a,A)
        j = n-ri
        if j >= p:
            l = i
            continue
        s = m
        for j in range(n-p+1):
            if i == j:
                continue
            s += min(m,A-a[j])
        s += m*(p-1)
        if s >= m*v:
            r = i
        else:
            l = i
    print((n-r))
    return

#Solve
if __name__ == "__main__":
    solve()