D - いろはちゃんとマス目 / Iroha and a Grid
Time limit : 2sec / Memory limit : 256MB
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 109+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 109+7.
Sample Input 1
Copy
2 3 1 1
Sample Output 1
Copy
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
Copy
10 7 3 4
Sample Output 2
Copy
3570
There are 12 forbidden cells.
Sample Input 3
Copy
100000 100000 99999 99999
Sample Output 3
Copy
1
Sample Input 4
Copy
100000 100000 44444 55555
Sample Output 4
Copy
738162020
解析:
看了这篇博客我觉得已经不用再说什么了。
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7;
int n,m,a,b,ans,mul[1000010];
inline void pre()
{
mul[0]=1;
for(int i=1;i<=1000000;i++) mul[i]=(mul[i-1]*i)%mod;
}
inline int ksm(int a,int b)
{
int ans=1;
a%=mod;
while(b)
{
if(b&1) ans=(ans*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return ans;
}
inline int C(int n,int m)
{
if(n>=0 && m>=0 && n>=m) return (mul[n]*ksm(mul[m],mod-2)%mod*ksm(mul[n-m],mod-2)%mod)%mod;
return 0;
}
signed main()
{
pre();
scanf("%d%d%d%d",&n,&m,&a,&b);
ans=C(n-1+m-1,n-1);
for(int j=1;j<=b;j++)
{
int i=n-a,sum=C(i-1+j-1,i-1)*C(n-i-1+m-j,n-i-1)%mod;
ans=((ans-sum)%mod+mod)%mod;
}
cout<<ans<<"\n";
return 0;
}