Description
N * N的方格,从左上到右下画一条线。一个机器人从左上走到右下,只能向右或向下走。并要求只能在这条线的上面或下面走,不能穿越这条线,有多少种不同的走法?由于方法数量可能很大,只需要输出Mod 10007的结果。
Input
输入一个数N(2 <= N <= 10^9)。
Output
输出走法的数量 Mod 10007。
Input示例
4
Output示例
10
解题思路
参照博客学习http://blog.csdn.net/hackbuteer1/article/details/7450250
类比于第一个题目,可以将横着类比为0,竖着走类比为1,很明显的卡特兰数的应用。但是由于n太大,需要使用Lucas定理来求组合数
lucas(n,m,p)=lucas(n/p,m/p,p)*C(n%p,m%p,p),
lucas(n,0,p)=1。
代码实现
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll p=10007;
ll quick_pow(ll a,ll b)
{
ll ans=1;
a%=p;
while(b>0)
{
if(b%2)
ans=ans*a%p;
a=a*a%p;
b/=2;
}
return ans;
}
ll calc(int n,int m)
{
ll a=1,b=1;
if(m>n) return 0;
while (m)
{
a=a*n%p;
b=b*m%p;
n--;
m--;
}
return a*quick_pow(b,p-2)%p;
}
ll lucas(ll n,ll m)
{
if(m==0)
return 1;
return calc(n%p,m%p)*lucas(n/p,m/p)%p;
}
int main()
{
ios::sync_with_stdio(false);
ll n;
cin>>n;
ll ans=lucas(2*n-2,n-1)%p*quick_pow(n,p-2)%p*2%p;
cout<<ans<<endl;
return 0;
}