HDU-5698 瞬间移动(杨辉三角 逆元 快速幂)
瞬间移动
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2538 Accepted Submission(s): 1105
Problem Description
有一个无限大的矩形,初始时你在左上角(即第一行第一列),每次你都可以选择一个右下方格子,并瞬移过去(如从下图中的红色格子能直接瞬移到蓝色格子),求到第n行第m列的格子有几种方案,答案对1000000007取模。
Input
多组测试数据。
两个整数n,m(2≤n,m≤100000)
Output
一个整数表示答案
Sample Input
4 5
Sample Output
10
思路: 找规律,可以发现是一个杨辉三角,然后就可以得到公式C(n+m-4,m-2)。逆元求解!!!
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const long long mod=1000000007;
const int maxn=2e5+7;
ll fac[maxn*2],inv_fac[maxn*2];
ll quickpow(ll x,ll n){
ll res=1;
x=x%mod;
while(n){
if(n&1)res=(res*x)%mod;
n>>=1;
x=(x*x)%mod;
}
return res;
}
void init(){
fac[0]=1;
for(int i=1;i<=maxn;i++) fac[i]=(fac[i-1]*i)%mod;
inv_fac[maxn]=quickpow(fac[maxn],mod-2);
for(int i=maxn-1;i>=0;i--) inv_fac[i]=(inv_fac[i+1]*(i+1))%mod;
}
ll C(int n,int m){
if(n < 0 || m < 0 || m > n) return 0;
if(m == 0 || m == n) return 1;
return fac[n]*inv_fac[n-m]%mod*inv_fac[m]%mod;
}
int n,m,k,T;
int main(){
init();
int n,m;
while(cin>>n>>m){
cout<<C(m+n-4,m-2)%mod<<endl;
}
return 0;
}