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 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include<stdio.h>

#define M 1000000007

long long int product(long long int a, long long int b){
    long long int result = 0;
    while (b > 0){
        if(b % 2 == 1){
            result += a;
            if(result >= M){
                result -= M;
            }
        }
        b = b/2;
        a = 2*a;
        if(a >= M){
            a -= M;
        }
    }
    return result;
}

long long int permutation(int n, int r){
    long long int x = 1;
    for(int i=0; i<r; i++){
        x = (x%M) * (n%M);
        n--;
    }
    return x;
}

long long int combination(int a, int b){
    long long int max, min;
    if(a>b){
        max = a;
        min = b;
    }else{
        max = b;
        min = a;
    }
    if(min == 0){
        return 1;
    }
    return permutation(a+b,min)/permutation(min, min);
}

void func(long long int* p1, long long int* p2, int* xs, int* ys, int n, int h, int w){
    for(int i=0; i<n; i++){
        if(i==0){
            *(p1) = combination(*(xs)-1, *(ys)-1);
            *(p2) = combination(w-*(xs), h-*(ys));
        }else{
            *(p1+i) = (*(p1+i-1) * ((   *(xs+i)  +    *(ys+i)  - 2) - (   *(ys+i)-1 ) + 1) / (*(ys+i) - 1)) % M;
            *(p2+i) = (*(p2+i-1) * (((h-*(ys+i)) + (w-*(xs+i))    ) - ((w-*(xs+i)  )) + 1) / (w - *(xs+i))) % M;
        }
    }
}

int main(){
    long long int count = 0;
    int h, w, a, b;
    scanf("%d %d %d %d", &h, &w, &a, &b);
    int buf = h-a;
    if(buf > w-b){
        buf = w-b;
    }
    long long int array1[buf], array2[buf];
    int xs[buf], ys[buf];
    for(int i=0; i<buf; i++){
        xs[i] = b+buf-i;
        ys[i] = h-a-buf+1+i;
    }
    func(array1, array2, xs, ys, buf, h, w);
    for(int i=0; i<buf; i++){
        //printf("(%d,%d) : %d %d\n", xs[i], ys[i], array1[i], array2[i]);
        count += product(array1[i], array2[i]);
        count = count % M;
    }

    printf("%d", count);

    return 0;
}