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 C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ABC_D
{
    class D058
    {

        static int _Mod = 1000000007;

        //累乗(a^n) O(logn)
        public static long ModPow(long a, int n)
        {
            long res = 1;
            while (n > 0)
            {
                if (n % 2 == 1) res = (res * a) % _Mod;
                a = (a * a) % _Mod;
                n >>= 1;
            }
            return res;
        }

        //逆元1/n(mod p) (1<=n<p)
        public static long InverseElement(long n)
        {
            return ModPow(n, _Mod - 2);
        }

        //階乗n!(mod p)のベクトル
        public static List<long> Factorial(int n)
        {
            long x = 1;
            List<long> list = new List<long>();
            list.Add(x);
            for (int i = 1; i <= n; i++)
            {
                x = (x * i) % _Mod;
                list.Add(x);
            }
            return list;
        }

        //階乗の逆元 1/n! (mod p)のベクトル
        public static List<long> InversePower(int n)
        {
            long x = 1;
            List<long> list = new List<long>();
            list.Add(x);
            for (int i = 1; i <= n; i++)
            {
                x = (x * InverseElement(i)) % _Mod;
                list.Add(x);
            }
            return list;
        }

        //組み合わせの数nCr (mod p)
        public static long Combination(int n, int r, List<long> power, List<long> inv)
        {
            long denominator = (inv[r] * inv[n - r]) % _Mod;
            long val = (power[n] * denominator) % _Mod;
            return val;
        }


        static void Main(string[] args)
        {
            int[] a = Console.ReadLine().Split(' ').Select(x => int.Parse(x)).ToArray();
            int H = a[0], W = a[1], A = a[2], B = a[3];

            List<long> power = Factorial(H + W);
            List<long> inv = InversePower(H + W);


            long sum = 0;
            for (int i = 0; i < H - A; i++)
            {
                long c1 = Combination(B + i - 1, i, power, inv) % _Mod;
                long c2 = Combination(W + H - B - i - 2, W - B - 1, power, inv) % _Mod;
                sum = (sum + c1 * c2) % _Mod;
            }
            Console.WriteLine(sum);
        }

    }
}