Problem:
Score : 700 points

Problem Statement

N problems are proposed for an upcoming contest. Problem i has an initial integer score of A_i points.

M judges are about to vote for problems they like. Each judge will choose exactly V problems, independently from the other judges,
and increase the score of each chosen problem by 1.

After all M judges cast their vote, the problems will be sorted in non-increasing order of score, and the first P problems will be chosen for the problemset.
Problems with the same score can be ordered arbitrarily, this order is decided by the chief judge.

How many problems out of the given N have a chance to be chosen for the problemset?

Constraints

2 \le N \le 10^5

1 \le M \le 10^9

1 \le V \le N - 1

1 \le P \le N - 1

0 \le A_i \le 10^9

Input

Input is given from Standard Input in the following format:

N M V P
A_1 A_2 ... A_N

Output

Print the number of problems that have a chance to be chosen for the problemset.

Sample Input 1

6 1 2 2
2 1 1 3 0 2

Sample Output 1

5

If the only judge votes for problems 2 and 5, the scores will be 2 2 1 3 1 2.
The problemset will consist of problem 4 and one of problems 1, 2, or 6.

If the only judge votes for problems 3 and 4, the scores will be 2 1 2 4 0 2.
The problemset will consist of problem 4 and one of problems 1, 3, or 6.

Thus, problems 1, 2, 3, 4, and 6 have a chance to be chosen for the problemset. On the contrary, there is no way for problem 5 to be chosen.

Sample Input 2

6 1 5 2
2 1 1 3 0 2

Sample Output 2

3

Only problems 1, 4, and 6 have a chance to be chosen.

Sample Input 3

10 4 8 5
7 2 3 6 1 6 5 4 6 5

Sample Output 3

8

Solution in JavaScript (node.js v5.12) (judge verdict: Runtime Error)

/**
 * @param input string[]
 */
function Main(input) {
  /** @type number[] */
  const input0Numbered = input[0].split(' ').map(Number);
  const N = input0Numbered[0];
  const M = input0Numbered[1];
  const V = input0Numbered[2];
  const P = input0Numbered[3];
  /**
   * 昇順ソートしたもの
   * @type number[]
   */
  const alist = input[1].split(' ').map(Number).sort((v1, v2) => v1 - v2);

  /**
   * まず、昇順ソート
   * 1. 配列の最小数Kの重複分を配列から抜いて投票可能数もその分減らす
   * 2. 投票数 -= 1 ... Kに全票を入れるため
   * 3. KにM票入れた結果K2より少ない数がK以降にあれば、その差を抜いていく。その合計がMになったらv-=1これを繰り返し、余った分をRとする
   * 4. 配列の最後からv番目の数にM-Rを足した数がK2以下であれば5へ、それ以外は配列からKを抜いて1に戻る
   * 5. P位以内になれるものが見つかったら、それより少ない数を引いた問題数が結果となる
   */

  v = V;
  var ai, ai2, aj, r, j, reducedV, max = null;
  // 選ばれるための最小スコアを検索
  for (var i = 0; i < alist.length; i++) {
    // この問題と同等のスコアのものに投票していく
    while (alist[i] === alist[i + 1]) {
      i++;
      v--;
    }
    v--;
    // この問題の点数
    ai = alist[i];
    // この問題の最大点数
    ai2 = ai + M;

    r = 0;
    // aiより大きいもののうち、ai2より小さいものに順に投票していく
    for (j = i + 1; alist[j] < ai2; j++) {
      r += ai2 - alist[j];
    }
    reducedV = Math.floor(r / M);
    r = r % M;

    if (v <= reducedV) {
      // この時点ですべて投票済みならすべてにおいて最大となるため終了
      max = ai;
      break;
    }

    // この時点で v < alist.length - (i + 1)

    // 残りはすべてスコアが大きい順に投票
    voteds = alist.slice(-(v - reducedV)).map((aj) => aj + M);
    // 部分的に投票済みならそのうち最も少ない数から引いていく
    if (r > 0) {
      for (j = 0; j < voteds.length; j++) {
        aj = voteds[j];
        // ai2より少なくなる場合、同じ数になるまで引く
        if (aj - r < ai2) {
          voteds[j] = ai2;
          r -= aj - ai2;
        } else {
          voteds[j] -= r;
          r = 0;
          break;
        }
      }

      if (r > 0) {
        voteds[voteds.length - 1] -= r;
      }
    }

    for (k = 0; k < P; k++) {
      cmp = (k < veteds.length)
        ? veteds[veteds.length - k - 1]
        : alist[alist.length - k - 1];

      if (ai2 >= cmp) {
        max = ai;
        break;
      }
    }
    if (max) {
      break;
    }
  }

  // 最小値のインデックに戻す
  for (; i > 0; i--) {
    if (alist[i] !== alist[i - 1]) {
      break;
    }
  }

  answer = alist.length - i;

  console.log(answer);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8").trim().split("\n"));