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)

#[allow(unused_macros)]
macro_rules! scan {
    () => {
        {
            let mut line: String = String::new();
            std::io::stdin().read_line(&mut line).unwrap();
            line.trim().to_string()
        }
    };
    (;;) => {
        {
            let mut line: String = String::new();
            std::io::stdin().read_line(&mut line).unwrap();
            line.trim().split_whitespace().map(|s| s.to_string()).collect::<Vec<String>>()
        }
    };
    (;;$n:expr) => {
        {
            (0..$n).map(|_| scan!()).collect::<Vec<_>>()
        }
    };
    ($t:ty) => {
        {
            let mut line: String = String::new();
            std::io::stdin().read_line(&mut line).unwrap();
            line.trim().parse::<$t>().unwrap()
        }
    };
    ($($t:ty),*) => {
        {
            let mut line: String = String::new();
            std::io::stdin().read_line(&mut line).unwrap();
            let mut iter = line.split_whitespace();
            (
                $(iter.next().unwrap().parse::<$t>().unwrap(),)*
            )
        }
    };
    ($t:ty;;) => {
        {
            let mut line: String = String::new();
            std::io::stdin().read_line(&mut line).unwrap();
            line.split_whitespace()
                .map(|t| t.parse::<$t>().unwrap())
                .collect::<Vec<_>>()
        }
    };
    ($t:ty;;$n:expr) => {
        (0..$n).map(|_| scan!($t;;)).collect::<Vec<_>>()
    };
    ($t:ty; $n:expr) => {
        (0..$n).map(|_|
                    scan!($t)
        ).collect::<Vec<_>>()
    };
    ($($t:ty),*; $n:expr) => {
        (0..$n).map(|_|
                    scan!($($t),*)
        ).collect::<Vec<_>>()
    };
}

const MOD: i64 = 1_000_000_007;

fn fact(n: i64, memo: &mut [Option<i64>]) -> i64 {
    if let Some(v) = memo[n as usize] {
        v
    } else {
        let v = (1..n + 1).fold(1, |a, b| a * b % MOD);
        memo[n as usize] = Some(v);
        v
    }
}

fn pow(n: i64, k: i64) -> i64 {
    match k {
        0 => 1,
        a if a % 2 == 0 => pow(n * n % MOD, k / 2),
        _ => n * pow(n * n % MOD, k / 2) % MOD,
    }
}

fn combination(n: i64, k: i64, memo: &mut [Option<i64>]) -> i64 {
    (fact(n, memo) * pow(fact(k, memo), MOD - 2) % MOD) * pow(fact(n - k, memo), MOD - 2) % MOD
}

fn main() {
    let (h, w, a, b) = scan!(i64, i64, i64, i64);
    let mut memo = vec![None; (h + w) as usize];
    memo[0] = Some(1);
    for i in 0..memo.len() - 1 {
        memo[i + 1] = Some((i as i64 + 1) * memo[i].unwrap() % MOD);
    }

    let mut ans = 0;
    for i in 1..w - b + 1 {
        ans += combination(h - a + b + i - 2, h - a - 1, &mut memo)
            * combination(a + w - b + 1 - i - 2, a - 1, &mut memo)
            % MOD;
        ans %= MOD;
    }
    println!("{}", ans);
}