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)

//  ____            _                  _                       _       _
// |  _ \ _   _ ___| |_    ___ _ __   | |_ ___ _ __ ___  _ __ | | __ _| |_ ___
// | |_) | | | / __| __|  / __| '_ \  | __/ _ \ '_ ` _ \| '_ \| |/ _` | __/ _ \
// |  _ <| |_| \__ \ |_  | (__| |_) | | ||  __/ | | | | | |_) | | (_| | ||  __/
// |_| \_\\__,_|___/\__|  \___| .__/___\__\___|_| |_| |_| .__/|_|\__,_|\__\___|
//                            |_| |_____|               |_|

//                                                     _        _ _ _____  ___
//                               _ __ ___   __ _ _ __ | |_ __ _/ / |___ / / _ \
//                              | '_ ` _ \ / _` | '_ \| __/ _` | | | |_ \| | | |
//                              | | | | | | (_| | | | | || (_| | | |___) | |_| |
//                              |_| |_| |_|\__,_|_| |_|\__\__,_|_|_|____/ \___/

//https://github.com/manta1130/Competitive_Programming_Template_Rust

#[macro_use]
mod input {

    use std;
    use std::io;

    const SPLIT_DELIMITER: char = ' ';

    #[macro_export]
    #[allow(unused_macros)]
    macro_rules! input {
    ( $($x:expr ),*) => {
        {
            let temp_str = input_line_str();
            let mut split_result_iter = temp_str.split_whitespace();
                $(
                let buf_split_result = split_result_iter.next();
                let buf_split_result = buf_split_result.unwrap();
                    ($x) = buf_split_result.parse().unwrap();
                )*
        }
    };
}

    #[allow(dead_code)]
    pub fn input_line_str() -> String {
        let mut s = String::new();
        io::stdin().read_line(&mut s).unwrap();
        s.trim().to_string()
    }

    #[allow(dead_code)]
    pub fn p<T>(t: T)
    where
        T: std::fmt::Display,
    {
        println!("{}", t);
    }

    #[allow(dead_code)]
    pub fn input_vector2d<T>(line: usize) -> Vec<Vec<T>>
    where
        T: std::str::FromStr,
    {
        let mut v: Vec<Vec<T>> = Vec::new();

        for _ in 0..line {
            let vec_line = input_vector();
            v.push(vec_line);
        }
        v
    }

    #[allow(dead_code)]
    pub fn input_vector<T>() -> Vec<T>
    where
        T: std::str::FromStr,
    {
        let mut v: Vec<T> = Vec::new();

        let s = input_line_str();
        let split_result = s.split(SPLIT_DELIMITER);
        for z in split_result {
            let buf = match z.parse() {
                Ok(r) => r,
                Err(_) => panic!("Parse Error"),
            };
            v.push(buf);
        }
        v
    }

    #[allow(dead_code)]
    pub fn input_vector_row<T>(n: usize) -> Vec<T>
    where
        T: std::str::FromStr,
    {
        let mut v = Vec::with_capacity(n);
        for _ in 0..n {
            let buf = match input_line_str().parse() {
                Ok(r) => r,
                Err(_) => panic!("Parse Error"),
            };
            v.push(buf);
        }
        v
    }

    pub trait ToCharVec {
        fn to_charvec(&self) -> Vec<char>;
    }

    impl ToCharVec for String {
        fn to_charvec(&self) -> Vec<char> {
            self.to_string().chars().collect::<Vec<_>>()
        }
    }
}

mod modint {

use std;
use std::fmt;
use std::num::ParseIntError;
use std::ops;
use std::str::FromStr;

#[derive(PartialEq, Eq, Debug, Clone)]
pub struct Modint {
    p: usize, //
    v: usize,
}

const DEFAULT_MODNUM: usize = 1_000_000_007;

impl Modint {
    #[allow(dead_code)]
    pub fn new(p: usize) -> Modint {
        Modint { p: p, v: 0 }
    }
    #[allow(dead_code)]
    pub fn from(p: usize, v: usize) -> Modint {
        Modint { p: p, v: v % p }
    }
}

impl FromStr for Modint {
    type Err = ParseIntError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let num: usize;
        num = s.parse()?;
        Ok(Modint {
            p: DEFAULT_MODNUM,
            v: num,
        })
    }
}

//print用
impl fmt::Display for Modint {
    fn fmt<'a>(&self, f: &mut fmt::Formatter<'a>) -> fmt::Result {
        write!(f, "{}", self.v)
    }
}

//演算子関係
impl<'a> ops::Add for &'a Modint {
    type Output = Modint;

    #[allow(dead_code)]
    fn add(self, other: &'a Modint) -> Modint {
        if self.p != other.p {
            panic!("Mod Error");
        }
        Modint {
            p: self.p,
            v: (self.v + other.v) % self.p,
        }
    }
}

impl<'a> ops::Sub for &'a Modint {
    type Output = Modint;

    #[allow(dead_code)]
    fn sub(self, other: &'a Modint) -> Modint {
        if self.p != other.p {
            panic!("Mod Error");
        }
        Modint {
            p: self.p,
            v: (self.v + self.p - (other.v % self.p)) % self.p,
        }
    }
}

impl<'a> ops::Mul for &'a Modint {
    type Output = Modint;

    #[allow(dead_code)]
    fn mul(self, other: &'a Modint) -> Modint {
        if self.p != other.p {
            panic!("Mod Error");
        }
        Modint {
            p: self.p,
            v: (self.v * other.v) % self.p,
        }
    }
}

impl<'a> ops::Div for &'a Modint {
    type Output = Modint;

    fn div(self, other: &'a Modint) -> Modint {
        if self.p != other.p {
            panic!("Mod Error");
        }
        let mut obj = self.clone();
        obj.div_uint(other.v);
        obj
    }
}

//ToDo
//AddAssign,SubAssign,MulAssign,DivAssignを実装

impl Modint {
    #[allow(dead_code)]
    pub fn add_uint(&mut self, n: usize) -> &Self {
        self.v += n;
        self.v %= self.p;
        self
    }

    #[allow(dead_code)]
    pub fn sub_uint(&mut self, mut n: usize) -> &Self {
        n = n % self.p;
        self.v += self.p;
        self.v -= n;
        self.v %= self.p;
        self
    }

    #[allow(dead_code)]
    pub fn mul_uint(&mut self, n: usize) -> &Self {
        self.v *= n;
        self.v %= self.p;
        self
    }

    #[allow(dead_code)]
    pub fn div_uint(&mut self, n: usize) -> &Self {
        let mut obj = Modint::from(self.p, n);
        obj.inv();
        self.v *= obj.v;
        self.v %= self.p;
        self
    }

    #[allow(dead_code)]
    pub fn inv(&mut self) -> &Self {
        let p = self.p;
        self.pow(p - 2);
        self
    }

    #[allow(dead_code)]
    pub fn pow(&mut self, mut n: usize) -> &Self {
        let mut temp = self.v;
        self.v = 1;
        while n > 0 {
            if n & 1 != 0 {
                self.v *= temp;
                self.v %= self.p;
            }
            n >>= 1;
            temp *= temp;
            temp %= self.p;
        }
        self
    }

    #[allow(dead_code)]
    pub fn get_value(&self) -> usize {
        self.v
    }
}

pub struct DPFactorial {
    p: usize,
    normal: Vec<Modint>,
    inv: Vec<Modint>,
}
impl DPFactorial {
    #[allow(dead_code)]
    pub fn new(p: usize) -> DPFactorial {
        let mut obj = DPFactorial {
            p: p,
            normal: Vec::new(),
            inv: Vec::new(),
        };
        obj.normal.push(Modint::from(p, 1));
        obj.inv.push(Modint::from(p, 1));
        obj
    }

    #[allow(dead_code)]
    pub fn get_factorial(&mut self, n: usize) -> Modint {
        if n < self.normal.len() {
            return self.normal[n].clone();
        }
        for z in self.normal.len()..n + 1 {
            let buf = Modint::from(self.p, z);
            let buf = &buf * &self.normal[z - 1];

            self.normal.push(buf);
        }
        return self.normal[n].clone();
    }

    #[allow(dead_code)]
    pub fn get_factorial_inv(&mut self, n: usize) -> Modint {
        if n < self.inv.len() {
            return self.inv[n].clone();
        }
        for z in self.inv.len()..n + 1 {
            let mut buf = Modint::from(self.p, z);
            buf.inv();
            let buf = &buf * &self.inv[z - 1];
            self.inv.push(buf);
        }
        self.inv[n].clone()
    }

    #[allow(dead_code)]
    pub fn get_combination(&mut self, n: usize, r: usize) -> Modint {
        if n < r {
            return Modint::from(self.p, 0);
        }
        &(&self.get_factorial(n) * &(self.get_factorial_inv(n - r))) * &(self.get_factorial_inv(r))
    }

    #[allow(dead_code)]
    pub fn get_permutation(&mut self, n: usize, r: usize) -> Modint {
        if n < r {
            return Modint::from(self.p, 0);
        }
        &self.get_factorial(n) * &(self.get_factorial_inv(n - r))
    }
}
}



use input::*;
use modint::*;

fn main() {
    let mut dpf = DPFactorial::new(1_000_000_007);
    let (h, w, a, b): (usize, usize, usize, usize);
    input!(h, w, a, b);
    let mut ans = Modint::new(1_000_000_007);
    for i in b..w {
        let mut buf = dpf.get_combination(i + (h - a)-1,i);
        buf = &buf * &dpf.get_combination(a + w - i - 2, w-i-1);
        ans = &ans + &buf;
    }
    p(ans);
}