【分析】如果n,m范围小点,就是最基础的DP,但是这题n,m<=10^6,不能DP;其实就是个简单的组合数学(然而已经忘记了):
从(1,1)走到(n,m)一共需要往下走n-1步,往右走m-1步,那么一共可能的路径数量就是从(n-1+m-1)中选择出(n-1)条往下走,那么组合数就是C(n-1+m-1,n-1);有除法,加个快速幂逆元就好了。
【AC CODE】46ms
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define rep(i,a,n) for(int i = a; i < n; i++)
#define repe(i,a,n) for(int i = a; i <= n; i++)
#define per(i,n,a) for(int i = n; i >= a; i--)
#define clc(a,b) memset(a,b,sizeof(a))
const int INF = 0x3f3f3f3f, MAXN = 2000000+10;
const LL MOD = (LL)1e9+7;
LL f[MAXN];
LL pow_mod(LL x, int n)
{
LL ans = 1;
while(n)
{
if(n&1) ans = ans*x%MOD;
x = x*x%MOD;
n >>= 1;
}
return ans;
}
int main()
{
#ifdef SHY
freopen("d:\\1.txt", "r", stdin);
#endif
int n,m;
scanf("%d%d", &n, &m);
f[1] = 1;
repe(i,2,n+m-2) f[i] = f[i-1]*i%MOD;
LL a = f[n+m-2], b = f[m-1]*f[n-1]%MOD;
printf("%lld\n", a*pow_mod(b,MOD-2)%MOD);
return 0;
}