F - 瞬间移动 HDU - 5698
有一个无限大的矩形,初始时你在左上角(即第一行第一列),每次你都可以选择一个右下方格子,并瞬移过去(如从下图中的红色格子能直接瞬移到蓝色格子),求到第nn行第mm列的格子有几种方案,答案对10000000071000000007取模。
Input
多组测试数据。
两个整数n,m(2≤n,m≤100000)n,m(2≤n,m≤100000)
Output
一个整数表示答案
Sample Input
4 5
Sample Output
10
推着推着会发现答案是C(n+m-4,n-2)
因为 2<=n,m<=1000000,直接逆元打表,*inv[n] 就代表 /n!
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=1e9+7;
ll fac[1000005],inv[1000005];
ll quickpow(ll a,ll b)
{
ll ret=1;
while(b)
{
if(b&1) ret=(ret*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ret;
}
void init(int p)
{
fac[0]=1;
for(int i=1;i<=p;i++)
fac[i]=(fac[i-1]*i)%mod;
inv[p]=quickpow(fac[p],mod-2);
for(int i=p-1;i>=0;i--)
{
inv[i]=(inv[i+1]*(i+1))%mod;
}
}
ll C(ll n,ll m)
{
return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int main()
{
init(1000001);
ll n,m;
while(~scanf("%lld%lld",&n,&m))
{
printf("%lld\n",C(n+m-4,n-2));
}
return 0;
}