组合数

C - 瞬间移动

有一个无限大的矩形,初始时你在左上角(即第一行第一列),每次你都可以选择一个右下方格子,并瞬移过去(如从下图中的红色格子能直接瞬移到蓝色格子),求到第nn行第mm列的格子有几种方案,答案对10000000071000000007取模。

 

Input多组测试数据。

两个整数n,m(2n,m100000)n,m(2≤n,m≤100000)
Output一个整数表示答案Sample Input

4 5

Sample Output

10

解析:找规律,规律为c (n+m-4)(m-2)
AC带码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
inline int read() {int x=0,f=1;char c=getchar();while(c!='-'&&(c<'0'||c>'9'))c=getchar();if(c=='-')f=-1,c=getchar();while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return f*x;}
typedef long long ll;
const int maxn=5e5+10;
const ll M=1000000007;
const int INF=0x3f3f3f3f;//c (n+m-4)(m-2)
ll n,m;
ll j[maxn];
ll kuai(ll a,ll b){
    ll ans=1;
    while(b){
        if(b%2==1){
            ans=(ans*a)%M;
        }
        a=a*a%M;
        b/=2;
    }
    return ans;
}
ll C(ll n,ll m){
    ll ans1=kuai(j[m],M-2)%M*kuai(j[n-m],M-2)%M;
    return j[n]*ans1%M;
} 
int main(){
    ll n,m;
    j[1]=1;
    for(ll i=2;i<maxn;i++){
        j[i]=i*j[i-1]%M;//阶乘打表 
    }
    while(cin>>n>>m){
        if(n==1||m==1){
            printf("0\n");
        }
        else if(n==2||m==2){
            printf("1\n");
        }
        else{
            printf("%lld\n",C(n+m-4,m-2)%M);
        }
    }
    return 0;
}
posted @ 2020-01-19 21:29  哎呦哎(iui)  阅读(156)  评论(0编辑  收藏  举报