【组合数学 逆元打表】 HDU - 5698 F - 瞬间移动

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;
}

猜你喜欢

转载自blog.csdn.net/qq_41037114/article/details/82960066
今日推荐