您的位置:首页 > 其它

51nod 1120 机器人走方格 V3 卡特兰数 lucas定理

2016-05-27 15:58 453 查看
N * N的方格,从左上到右下画一条线。一个机器人从左上走到右下,只能向右或向下走。并要求只能在这条线的上面或下面走,不能穿越这条线,有多少种不同的走法?由于方法数量可能很大,只需要输出Mod 10007的结果。

Input
输入一个数N(2 <= N <= 10^9)。

Output
输出走法的数量 Mod 10007。

Input示例
4

Output示例
10

明显是一道卡特兰数,推出ans = C(2*n-2,n-1) * 2 / n % MOD
先让n--,ans = C(2*n,n) * 2 / (n+1) % MOD 这样公式看起来好看些

由于 n <= 10^9,但是 MOD = 10007,所以求ans需要用到lucas定理



//File Name: nod1120.cpp
//Author: long
//Mail: 736726758@qq.com
//Created Time: 2016年05月27日 星期五 15时46分58秒

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>

#define LL long long

using namespace std;

const int MOD = 10007;

LL jie[MOD];

LL qp(LL x,LL y){
LL res = 1;
while(y){
if(y & 1) res = res * x % MOD;
x = x * x % MOD;
y >>= 1;
}
return res;
}

void init(){
jie[0] = 1;
for(int i=1;i<MOD;i++)
jie[i] = jie[i-1] * i % MOD;
}

LL get_c(int x,int y){
if(y == 0 || y == x) return 1;
return jie[x] * qp(jie[y] * jie[x-y] % MOD,MOD - 2) % MOD;
}

LL lucas(LL x,LL y){
LL ans = 1;
int u,v;
while(x > 0 || y > 0){
u = x % MOD;
v = y % MOD;
ans = ans * get_c(u,v) % MOD;
x /= MOD;
y /= MOD;
}
return ans;
}

int main(){
init();
int n;
while(~scanf("%d",&n)){
n--;
printf("%d\n",(int)lucas(2*n,n) * qp(n+1,MOD-2) * 2 % MOD);
}
return 0;
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: