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: Accepted)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h> // int64_t

#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a,b) ((a) > (b) ? (b) : (a))

int get_int2(int *a1, int *a2) {
  scanf("%d %d", a1, a2);
  return 0;
}

#define DIVISOR 1000000007
#define NUM_MAX 200000
// <arr[0]> <arr[1]> .. <arr[size-1]>
int fget_array(int *arr, int size) {
    int i;
    for(i = 0; i < size; i++) {
        scanf("%d", &arr[i]);
    }
    return 0;
}

struct point2d {
    int row;
    int col;
};

struct pair {
    int x;
    int y;
};

struct pair gcdext(int a, int b) {
    if(a==0) { return (struct pair){0, 1}; }
    struct pair p = gcdext(b%a, a);
    return (struct pair){p.y - (b/a)*p.x, p.x};
}
static int64_t factorial[NUM_MAX+1];
static int64_t inv_factorial[NUM_MAX+1];
void init_combi(int size) {
    factorial[0] = factorial[1] = 1;
    inv_factorial[0] = inv_factorial[1] = 1;
    int i;
    for(i = 2; i <= size; i++) {
        factorial[i] = (factorial[i-1] * i)%DIVISOR;
        struct pair p = gcdext(i, DIVISOR);
        int inv = (p.x + DIVISOR)%DIVISOR;
        inv_factorial[i] = (inv_factorial[i-1] * inv)%DIVISOR;
    }
    return;
}

int64_t calc_combi(int n, int k) {
    if(k > n) return 0;
    int64_t ans = 1;
    ans = (ans * factorial[n])%DIVISOR;
    ans = (ans * inv_factorial[n-k])%DIVISOR;
    ans = (ans * inv_factorial[k])%DIVISOR;
    return ans;
}


int64_t calc_routes(struct point2d p1, struct point2d p2) {
    int rs = p2.row - p1.row;
    int cs = p2.col - p1.col;
    return calc_combi(rs+cs, rs);
}

int main(void) {
    int rows, cols;
    get_int2(&rows, &cols);
    // edge
    rows--; cols--;
    int a, b;
    get_int2(&a, &b);
    init_combi(rows+cols);

    int64_t ans = 0;
    // usually, calc_combi(rows-1+cols-1, cols-1)
    int r;
    struct point2d boundary = (struct point2d){rows-a, b};
    for(r = 0; r <= boundary.row; r++) {
        int64_t res = 1;
        // lefttop
        struct point2d start1 = (struct point2d){0, 0};
        struct point2d end1 = (struct point2d){r, boundary.col};
        res = (res * calc_routes(start1, end1));
        // rows-i-i
        // rightbottom: rows-i, cols-b-1
        struct point2d start2;
        if(r == boundary.row) {
            start2 = (struct point2d){r, boundary.col};
        } else {
            start2 = (struct point2d){r, boundary.col+1};
        }
        struct point2d end2 = (struct point2d){rows, cols};
        res = (res * calc_routes(start2, end2))%DIVISOR;
#ifdef DEBUG
        printf("topleft: (%d %d) -> (%d %d)  ",
            start1.row, start1.col,
            end1.row, end1.col
        );
        printf("bottomright: (%d %d) -> (%d %d)",
            start2.row, start2.col,
            end2.row, end2.col
        );
        printf(" -> %lld\n", res);
#endif
        ans = (ans + res)%DIVISOR;
    }
    printf("%d\n", (int)ans);
    return 0;
}