51Nod 1120 - 機器人走方格 V3(Lucas定理+Catalan數)
阿新 • • 發佈:2018-11-09
題目連結 http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1120
【題目描述】
N * N的方格,從左上到右下畫一條線。一個機器人從左上走到右下,只能向右或向下走。並要求只能在這條線的上面或下面走,不能穿越這條線,有多少種不同的走法?由於方法數量可能很大,只需要輸出Mod 10007的結果。
Input
輸入一個數N(2 <= N <= 10^9)。
Output
輸出走法的數量 Mod 10007。
Input示例
4
Output示例
10
【思路】
卡特蘭數,模數比較小用Lucas定理
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=10010; const int mod=10007; ll pw(ll x,ll n){ ll ans=1; while(n){ if(n&1) ans=ans*x%mod; x=x*x%mod; n>>=1; } return ans; } ll inv(ll a){return pw(a,mod-2);} ll fac[maxn]; ll invfac[maxn]; void init(){ fac[0]=1; invfac[0]=1; for(int i=1;i<maxn;++i){ fac[i]=fac[i-1]*(ll)i%mod; invfac[i]=inv(fac[i]); } } ll C(int n,int m){ return fac[n]*invfac[m]%mod*invfac[n-m]%mod; } ll Lucas(int n,int m){ if(m>n) return 0LL; ll ans=1LL; for(;m;n/=mod,m/=mod) ans=ans*C(n%mod,m%mod)%mod; return ans; } ll Cat(int n){ return ((Lucas(2*n,n)-Lucas(2*n,n-1))%mod+mod)%mod; } int main(){ init(); int n; scanf("%d",&n); printf("%lld\n",2LL*Cat(n-1)%mod); return 0; }