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 Rust (1.15.1) (judge verdict: Accepted)

use std::io;

static MOD: i64 = 1_000_000_007;

struct Solver {
    max: i64,
    factorials: Vec<i64>,
    inv_factorials: Vec<i64>,
}

fn pow(x_: i64, y_: i64) -> i64 {
    let mut x = x_ % MOD;
    let mut y = y_;
    if x == 0 || x == 1 {
        return x;
    }
    let mut prod = 1;
    while y > 0 {
        if y % 2 == 0 {
            x = x * x % MOD;
            y /= 2;
        } else {
            prod = prod * x % MOD;
            y -= 1;
        }
    }
    prod
}

#[test]
fn test_pow() {
    assert_eq!(pow(1, 100), 1);

    assert_eq!(pow(2, 1), 2);
    assert_eq!(pow(2, 2), 4);
    assert_eq!(pow(2, 3), 8);
    assert_eq!(pow(2, 16), 65536);
}

fn inverse(x: i64) -> i64 {
    pow(x, MOD - 2)
}

#[test]
fn test_inverse() {
    assert_eq!((1 * inverse(1)) % MOD, 1);
    assert_eq!((2 * inverse(2)) % MOD, 1);
    assert_eq!((123 * inverse(123)) % MOD, 1);
    assert_eq!((987_654 * inverse(987_654)) % MOD, 1);
    assert_eq!((321_654_987 * inverse(321_654_987)) % MOD, 1);
}

fn factorial(n: i64) -> i64 {
    let mut prod = 1;
    for i in 1..(n+1) {
        prod = (prod * i) % MOD;
    }
    prod
}

#[test]
fn test_factorial_small() {
    assert_eq!(factorial(0), 1);
    assert_eq!(factorial(1), 1);
    assert_eq!(factorial(3), 3 * 2 * 1);
    assert_eq!(factorial(10), 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1);
}

#[test]
fn test_factorial_large() {
    let numbers = vec![123, 123_456];
    for n in numbers {
        let actual = factorial(n);
        let mut expected = 1;
        for i in 2..(n+1) {
            expected = expected * i % MOD;
        }
        assert_eq!(actual, expected);
    }
}

fn init_inv_factorials(n: i64) -> Vec<i64> {
    let mut fs = Vec::with_capacity((n + 1) as usize);
    let mut cur = inverse(factorial(n));
    let mut k = n;
    for _ in 0..n {
        fs.push(cur);
        cur = (cur * k) % MOD;
        k -= 1;
    }
    fs.push(1);
    fs
}

#[test]
fn test_init_inv_factorials_with_zero() {
    let fs = init_inv_factorials(0);
    assert_eq!(fs.len(), 1);
    assert_eq!(fs[0], 1);
}

#[test]
fn test_init_inv_factorials() {
    let n = 100;
    let fs = init_inv_factorials(n);
    assert_eq!(fs.len(), (n + 1) as usize);
    for i in 0..(n+1) {
        assert_eq!(fs[i as usize], inverse(factorial((n - i))));
    }
}

fn init_factorials(n: i64) -> Vec<i64> {
    let mut fs = Vec::with_capacity((n + 1) as usize);
    let mut cur = 1;
    for k in 1..(n+1) {
        fs.push(cur);
        cur = (cur * k) % MOD;
    }
    fs.push(cur);
    fs
}

#[test]
fn test_init_factorials_with_zero() {
    let fs = init_factorials(0);
    assert_eq!(fs.len(), 1);
    assert_eq!(fs[0], 1);
}

#[test]
fn test_init_factorials() {
    let n = 100;
    let fs = init_factorials(n);
    assert_eq!(fs.len(), (n + 1) as usize);
    for i in 0..(n+1) {
        assert_eq!(fs[i as usize], factorial(i));
    }
}

impl Solver {
    fn new(max: i64) -> Self {
        return Solver{
            max: max,
            factorials: init_factorials(max),
            inv_factorials: init_inv_factorials(max),
        }
    }

    fn factorial(&self, n: i64) -> i64 {
        self.factorials[n as usize]
    }

    fn inv_factorial(&self, n: i64) -> i64 {
        self.inv_factorials[(self.max - n) as usize]
    }

    fn comb(&self, n: i64, r: i64) -> i64 {
        let mut result = self.factorial(n);
        result = result * self.inv_factorial(r) % MOD;
        result = result * self.inv_factorial(n - r) % MOD;
        result
    }

    fn total_patterns(&self, ix: i64, iy: i64, ox: i64, oy: i64) -> i64 {
        let dx = ox - ix;
        let dy = oy - iy;
        self.comb(dx + dy, dx)
    }

    fn patterns_via(&self, w: i64, h: i64, ix: i64, iy: i64) -> i64 {
        let mut result = self.total_patterns(1, 1, ix, iy - 1);
        result = result * self.total_patterns(ix, iy, w, h) % MOD;
        result
    }

    fn solve(&self, w: i64, h: i64, a: i64, b: i64) -> i64 {
        let mut result = self.total_patterns(1, 1, w, h);
        // println!("total: {}", result);
        for ix in 1..(b+1) {
            let iy = h - a + 1;
            result -= self.patterns_via(w, h, ix, iy);
            if result < 0 {
                result += MOD;
            }
        }
        // println!("result: {}", result);
        result
    }
}

#[test]
fn test_solver_factorial() {
    let m = 100;
    let solver = Solver::new(m);
    for i in 0..(m+1) {
        assert_eq!(solver.factorial(i), factorial(i));
    }
}

#[test]
fn test_solver_inv_factorial() {
    let m = 100;
    let solver = Solver::new(m);
    for i in 0..(m+1) {
        assert_eq!(solver.inv_factorial(i), inverse(factorial(i)));
    }
}

#[test]
fn test_solver_comb() {
    let solver = Solver::new(100);
    assert_eq!(solver.comb(1, 1), 1);
    assert_eq!(solver.comb(2, 1), 2);
    assert_eq!(solver.comb(2, 2), 1);
    assert_eq!(solver.comb(10, 3), 120);
    assert_eq!(solver.comb(100, 50), 538992043);
}

#[test]
fn test_solver_solve_1() {
    let solver = Solver::new(5);
    assert_eq!(solver.solve(3, 2, 1, 1), 2)
}

#[test]
fn test_solver_solve_2() {
    let solver = Solver::new(17);
    assert_eq!(solver.solve(7, 10, 3, 4), 3570);
}

#[test]
fn test_solver_solve_3() {
    let solver = Solver::new(200000);
    assert_eq!(solver.solve(100000, 100000, 99999, 99999), 1);
}

#[test]
fn test_solver_solve_4() {
    let solver = Solver::new(200000);
    assert_eq!(solver.solve(100000, 100000, 44444, 55555), 738162020);
}

fn main() {
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
    let mut iter = input.split_whitespace();
    let h: i64 = iter.next().unwrap().parse().unwrap();
    let w: i64 = iter.next().unwrap().parse().unwrap();
    let a: i64 = iter.next().unwrap().parse().unwrap();
    let b: i64 = iter.next().unwrap().parse().unwrap();
    if h <= a || w <= b {
        println!("0");
    }
    let solver = Solver::new(w + h);
    println!("{}", solver.solve(w, h, a, b));
}