Problem:
Score : 400 points

Problem Statement

We have a large square grid with H rows and W columns.
Iroha is now standing in the top-left cell.
She will repeat going right or down to the adjacent cell, until she reaches the bottom-right cell.

However, she cannot enter the cells in the intersection of the bottom A rows and the leftmost B columns. (That is, there are A×B forbidden cells.) There is no restriction on entering the other cells.

Find the number of ways she can travel to the bottom-right cell.

Since this number can be extremely large, print the number modulo 10^9+7.

Constraints

1 ≦ H, W ≦ 100,000

1 ≦ A < H

1 ≦ B < W

Input

The input is given from Standard Input in the following format:

H W A B

Output

Print the number of ways she can travel to the bottom-right cell, modulo 10^9+7.

Sample Input 1

2 3 1 1

Sample Output 1

2

We have a 2×3 grid, but entering the bottom-left cell is forbidden. The number of ways to travel is two: "Right, Right, Down" and "Right, Down, Right".

Sample Input 2

10 7 3 4

Sample Output 2

3570

There are 12 forbidden cells.

Sample Input 3

100000 100000 99999 99999

Sample Output 3

1

Sample Input 4

100000 100000 44444 55555

Sample Output 4

738162020

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.util.*;
public class Main {
	static final long MOD = 1000000007L;

	public static void main(String[] args){
		Main main = new Main();
		main.solveD();
	}

	private void solveA() {
		Scanner sc = new Scanner(System.in);
		int five = 0;
		int seven = 0;
		for (int i = 0; i < 3; i++) {
			switch (sc.nextInt()) {
			case 5:
				five++;
				break;
			case 7:
				seven++;
				break;
			default:
			}
		}
		if (five == 2 && seven == 1) {
			System.out.println("YES");
		} else {
			System.out.println("NO");
		}
	}

	private void solveB() {
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		int L = sc.nextInt();
		List<String> list = new ArrayList<String>();
		for (int i = 0; i < N; i++) {
			list.add(sc.next());
		}
		Collections.sort(list);
		for (String str : list) {
			System.out.print(str);
		}
		System.out.println();
	}

	private void solveC() {
		Scanner sc = new Scanner(System.in);
		String N = sc.next();
		int K = sc.nextInt();
		boolean[] forbid = new boolean[10];
		int[] next = new int[10];
		for (int i = 0; i < 10; i++) {
			forbid[i] = false;
			next[i] = i;
		}
		for (int i = 0; i < K; i++) {
			forbid[sc.nextInt()] = true;
		}
		for (int i = 0; i < 10; i++) {
			for (int j = 0; j < 10; j++) {
				if (!forbid[(i + j) % 10]) {
					next[i] = i + j;
					break;
				}
			}
		}

		int L = N.length();
		String answer = "";
		boolean lift = false;
		for (int i = 0; i < N.length(); i++) {
			char c = N.charAt(L - i - 1);
			int ctoi = c - '0' + (lift ? 1 : 0);
			int ni = next[ctoi % 10] % 10;
			if (ctoi == ni) {
				answer = ni + answer;
			} else {
				int AL = answer.length();
				answer = "" + ni;
				for (int j = 0; j < AL; j++) {
					answer = answer + next[0];
				}
			}
			lift = (ctoi >= 10 || next[ctoi] >= 10);
		}
		if (lift) {
			System.out.print(next[1]);
		}
		System.out.println(answer);
	}

	private void solveD() {
		Scanner sc = new Scanner(System.in);
		long H = sc.nextLong();
		long W = sc.nextLong();
		long A = sc.nextLong();
		long B = sc.nextLong();

		long startRowIndex = H - A;
		long startColIndex = B + 1L;
		long answer = 0L;
		for (long shiftIndex = 0L; startRowIndex - shiftIndex > 0L && startColIndex + shiftIndex <= W; shiftIndex++) {
			answer += pointComb(H, W, H - A - shiftIndex, B + 1L + shiftIndex);
			answer %= MOD;
		}
		System.out.println(answer);
	}

	/**
	 * h行w列の格子について点(r, c)を通る組み合わせを求めます
	 * @param h 格子の行数
	 * @param w 格子の列数
	 * @param r 通る点の行index
	 * @param c 通る点の列index
	 * @return C(r + c - 2, c - 1) * C(h - r + w - c, w - c)
	 */
	private long pointComb(long h, long w, long r, long c) {
		if (r < 1 || c < 1 || r > h || c > w) return 1;
		return combination(r + c - 2L, c - 1L) * combination(h - r + w - c, w - c);
	}

	/**
	 * n個からm個選ぶ組み合わせの数を求めます
	 * @param n 全体の数
	 * @param m 選ぶ数
	 * @return C(n, m)
	 */
	private long combination(long n, long m) {
		if (n / 2L < m) {
			return combination(n , n - m);
		}
		if (m <= 0) {
			return 1L;
		}
		return (combination(n, m - 1) * (n - m + 1) / m) % MOD;
	}
}