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 Haskell (GHC 7.10.3) (judge verdict: Wrong Answer)


import Data.List
import Control.Applicative
import qualified Control.Monad.State as ST
import qualified Data.Map as M
type Ma = M.Map (Int,Int) Integer
type St = ST.State Ma Integer
  
main = do
  p <- getContents
  let fstline = words $ head $ lines p 
      h = read $ fstline !! 0 ::Integer
      w = read $ fstline !! 1 :: Integer
      a = read $ fstline !! 2 :: Integer
      b = read $ fstline !! 3 ::Integer
      m = M.empty :: Ma  
  putStr $  show $ getNum' h w a b !! ( getTtoN ( w - 1, h - 1) h ) -- ToDo
  

getNum' :: Integer-> Integer-> Integer -> Integer -> [Integer]
getNum' h w a b = target 
  where target = [ getListElement n | n <- [0..] ] 
          where getListElement n | y > ( ( h - 1 ) - a) && x <= ( b - 1)  = 0
                                 | x == 0 = y
                                 | y == 0 = x   
                                 | otherwise = target !! ( getTtoN (x - 1 ,y) h ) + target !! ( getTtoN (x, y -1) h ) 
                                   where (x, y) = getNtoT h n 
  
getX :: Integer -> Integer-> Integer
getX h n  = n `div` h
getY :: Integer -> Integer -> Integer
getY h n = n `mod` h
getNtoT :: Integer -> Integer -> (Integer, Integer)
getNtoT h n = (getX h n , getY h n)
getTtoN :: (Integer, Integer) -> Integer -> Int
getTtoN (x,y) h = fromIntegral (x * h + y)
  
getNum :: Ma  -> (Int, Int) -> Integer
getNum m (1,1) = 0
getNum m (1,2) = 1        
getNum m (2,1) = 1
getNum m (x,y) | re  == Nothing =  lef + abo
               | otherwise =  (\(Just x) -> x) re 
  where re = M.lookup (x,y) m
        lef =   getNum m ( (x - 1) , y ) 
        abo =   getNum m ( x, (y - 1) )

memorize :: Ma -> (Int, Int) -> Ma
memorize m (x,y) | M.lookup (x,y) m == Nothing = M.insert (x, y) re m
                 | otherwise = m
  where re = getNum m (x,y)

runMemo :: Ma -> (Int,Int) -> Ma      
runMemo m  (x, y)  = m   --f (m , (x,y))                     
  where xs = [1..x]
        ys = [1..y]
        
--initiarize :: Ma -> Int -> Int -> Int -> Int -> Ma
--initiarize m h w a b = map ( M.insert undefined